8
votes

Comportement étrange du château Windsor avec injection de propriété et méthode d'usine

J'utilise le château Windsor 2.5.1 dans un projet ASP.NET MVC et à l'aide d'une injection de propriété pour créer un objet que je m'attends toujours à être disponible sur une classe de contrôleur de base. J'utilise une usine pour créer cet objet, mais s'il y a une erreur dans le constructeur, je ne reçois pas de windsor du tout et cela renvoie mon objet mais sans injecter la propriété.

Est-ce le comportement attendu et si oui, comment puis-je obtenir une erreur soulevée lorsqu'une usine ne renonce à rien? p>

Voici un exemple P>

public class MyDependency : IMyDependency
{
    public MyDependency(bool error)
    {
        if (error) throw new Exception("I error on creation");
    }
}

public interface IMyDependency
{
}

public class MyConsumer
{
    public IMyDependency MyDependency { get; set; }
}

[TestFixture]
public class ProgramTest
{
    [Test]
    public void CreateWithoutError() //Works as expected
    {
        var container = new WindsorContainer().Register(
            Component.For<IMyDependency>().UsingFactoryMethod(() => new MyDependency(false)).LifeStyle.Transient,
            Component.For<MyConsumer>().LifeStyle.Transient
        );

        var consumer = container.Resolve<MyConsumer>();

        Assert.IsNotNull(consumer);
        Assert.IsNotNull(consumer.MyDependency);
    }

    [Test]
    public void CreateWithError_WhatShouldHappen() //I would expect an error since it can't create MyDependency
    {
        var container = new WindsorContainer().Register(
            Component.For<IMyDependency>().UsingFactoryMethod(() => new MyDependency(true)).LifeStyle.Transient,
            Component.For<MyConsumer>().LifeStyle.Transient
        );

        Assert.Throws<Exception>(() => container.Resolve<MyConsumer>());
    }

    [Test]
    public void CreateWithError_WhatActuallyHappens() //Gives me back a consumer, but ignores MyDependency
    {
        var container = new WindsorContainer().Register(
            Component.For<IMyDependency>().UsingFactoryMethod(() => new MyDependency(true)).LifeStyle.Transient,
            Component.For<MyConsumer>().LifeStyle.Transient
        );

        var consumer = container.Resolve<MyConsumer>();

        Assert.IsNotNull(consumer);
        Assert.IsNull(consumer.MyDependency); //Basically fails silently!
    }
}


0 commentaires

3 Réponses :


5
votes

Autant que je sache, oui, c'est le comportement prévu. Ce n'est pas spécifique aux méthodes d'usine, cela fonctionne comme celle pour toutes les dépendances de service optionnelles. Les dépendances facultatives qui jettent lors de la résolution sont traitées comme non résolvables. Ceci est défini dans par défautComponCenterActivator.ObtainPropertyValue ()

Bien sûr, vous pouvez toujours remplacer l'activateur par défaut avec votre propre si vous souhaitez modifier ce comportement.


1 commentaires

Merci, la réponse est sur place! Je peux travailler autour de cela à deux manières, donc ce n'est pas un problème



5
votes

ainsi que l'option suggérée par Mauricio, il est également possible de créer une installation pour atteindre le comportement attendu comme expliqué sur Cette exemple de page sur les installations.

Voici mon implémentation légèrement plus concise: xxx

Ensuite, décorer toutes les propriétés avec [non ouvertions] et vous recevrez une erreur s'il y a un problème avec la construction.


1 commentaires

Parfait! Si quelqu'un de lecture ne peut pas se souvenir de la syntaxe pour installer des installations (comme moi), appelez simplement conteneur.Addddfacility () lors de vos routines de bootstrap



0
votes

comme du château Windsor 3.2 Il y a une nouvelle addition fraîche qui est Journalisation de diagnostic dans le conteneur .

Donc, si vous faites cela par exemple dans une application ASP.NET MVC: P>

var logger = _container.Resolve<ILogger>();
((IKernelInternal)_container.Kernel).Logger = logger;
  • Lorsque Windsor essaie de résoudre une dépendance optionnelle (comme injection de propriété), mais échoue à une exception, l'exception est enregistrée. Li>
  • Lors de l'enregistrement d'un type par convention et de l'ignorer en raison d'une inscription existante pour ce type, ce fait est enregistré. Li> ul> p>


0 commentaires