Sollte ich die übergabe eines Unity-Container, in meinen Abhängigkeiten?

Also ich habe:

Anwendung: Erfordert Klasse B (andere Baugruppe)

Klasse B: Erfordert die C-Klasse (auch andere Baugruppe)

Klasse C: Nutzt einen Behälter zum auflösen verschiedener Objekte, sondern auch die Lebensdauer des Containers (und die Objekte, die es behebt) sollte kontrolliert werden durch die Zusammensetzung root.

Ich glaube, ich verstehe, wie das funktionieren würde unter den meisten Umständen, aber in der Klasse C, die ich brauche, um zu beheben, basierend auf einer Eigenschaft des Objekts, das übergeben wird.

Ich denke, was ich verlange ist, hat der container geworden, eine Abhängigkeit, und als solche, wie am besten, um es zu bekommen wo es gebraucht wird (nicht sicher, dass ich wirklich gerne führen Sie es durch eine Reihe von Konstruktoren - würde Eigenschaft der Injektion der Weg zu gehen?)

Ich glaube, diese Quelle ist so sauber und einfach wie ich kann:

namespace InjectionTest
{
    using System;
    using Microsoft.Practices.Unity;

    public class ApplicationA
    {
        static void Main(string[] args)
        {
            using (IUnityContainer container = new UnityContainer())
            {
                //Normally I'd use this, but for clarity in the example, I'm doing it in code.
                //container.LoadConfiguration(); 
                container.RegisterType<IClassB, ClassB>();
                container.RegisterType<IClassC, ClassC>();
                container.RegisterType<IFooBuilder, FrobBuilder>("frob");
                container.RegisterType<IFooBuilder, WidgetBuilder>("widget");
                IClassB machine = container.Resolve<IClassB>();
                InitialObject bar = new InitialObject() { Name = "widget" };
                machine.doSomethingWithBar(bar);
                bar = new InitialObject() { Name = "frob" };
                machine.doSomethingWithBar(bar);
            }
        }
    }

    public class ClassB : IClassB
    {
        IClassC classC { get; private set; }

        public ClassB(IClassC classc)
        {
            this.classC = classc;
        }

        public void doSomethingWithBar(InitialObject bar)
        {
            var foo = this.classC.BuildMyFoo(bar);
            /*
             * Do something else with foo & bar
             * */
        }

    }

    public interface IClassB
    {
        void doSomethingWithBar(InitialObject bar);
    }

    public class ClassC : IClassC
    {
        public ResultObject BuildMyFoo(InitialObject bar)
        {
            IFooBuilder builder = null;
            //How best do I get my container here?
            //IFooBuilder builder = container.Resolve<IFooBuilder>(bar.Name);
            return builder.build(bar);
        }
    }

    public interface IClassC
    {
        ResultObject BuildMyFoo(InitialObject bar);
    }

    public class InitialObject
    {
        public string Name { get; set; }
    }

    public class ResultObject
    {
        public string SomeOtherData { get; set; }
    }

    public interface IFooBuilder
    {
        ResultObject build(InitialObject bar);
    }

    public class FrobBuilder : IFooBuilder
    {
        public ResultObject build(InitialObject bar)
        {
            throw new NotImplementedException();
        }
    }

    public class WidgetBuilder : IFooBuilder
    {
        public ResultObject build(InitialObject bar)
        {
            throw new NotImplementedException();
        }
    }
}

Edit: Dies ist, wie ich es zu arbeiten mit property injection:

Änderte ich ClassC:

public class ClassC : IClassC
{
    [Dependency]
    public IUnityContainer Container { get; set; }

    public ResultObject BuildMyFoo(InitialObject bar)
    {
        IFooBuilder builder = null;
        //How best do I get my container here?
        builder = Container.Resolve<IFooBuilder>(bar.Name);
        return builder.build(bar);
    }
}

aktualisiert und meine Main-Methode in ApplicationA:

    public void Main()
    {
        using (IUnityContainer container = new UnityContainer())
        {
            //Normally I'd use this, but for clarity in the example, I'm doing it in code.
            //container.LoadConfiguration(); 
            container.RegisterType<IClassB, ClassB>();
            container.RegisterType<IClassC, ClassC>();
            container.RegisterType<IFooBuilder, FrobBuilder>("frob");
            container.RegisterType<IFooBuilder, WidgetBuilder>("widget");
            using (IUnityContainer child = container.CreateChildContainer())
            {
                container.RegisterInstance<IUnityContainer>(child);
                IClassB machine = container.Resolve<IClassB>();
                InitialObject bar = new InitialObject() { Name = "widget" };
                machine.doSomethingWithBar(bar);
                bar = new InitialObject() { Name = "frob" };
                machine.doSomethingWithBar(bar);
            }
        }
    }
  • OK, So beendete ich dieses Beispiel und habe es ausgeführt. property injection sieht aus wie der Weg zu gehen, ich habe nur zu registrieren, eine untergeordnete container als die Instanz, die ich verwenden möchten (Registrierung der top-level-container-Ergebnisse in einem stack-überlauf). Ich würde schätzen noch keine Antworten da bin ich neu hier DI Sachen.
  • Ok, jetzt sehe ich hier stackoverflow.com/questions/827756/..., dass ich gar nicht zum erstellen einer Kind - ich muss nur markieren die Eigenschaft als Abhängigkeit und Einheit auto-bringt der aktuelle container. Ich denke, das ist auch sauberer.
  • Verwandte: stackoverflow.com/questions/2386487/...
Schreibe einen Kommentar