Frage

Ich habe die Artikel auf MSDN über Unity (Dependency Injection, Inversion of Control) zu lesen, aber ich glaube, ich brauche es in einfachen Worten erklärt (oder einfache Beispiele). Ich bin vertraut mit dem MVPC Muster (wir es hier verwenden), aber ich kann einfach nicht wirklich diese Einheit Sache noch erfassen, und ich denke, es ist der nächste Schritt in unserem Anwendungsdesign.

War es hilfreich?

Lösung

Einheit ist nur ein IoC "Container". Google StructureMap und versuchen Sie es stattdessen aus. Ein bisschen leichter grok, glaube ich, wenn das IOK Zeug ist neu für Sie.

Grundsätzlich, wenn Sie IoC verstehen dann verstehen Sie, dass das, was Sie tun, ist die Steuerung zum Umkehren, wenn ein Objekt erstellt wird.

Ohne IoC:

public class MyClass
{
   IMyService _myService; 

   public MyClass()
   {
      _myService = new SomeConcreteService();    
   }
}

Mit IoC-Container:

public class MyClass
{
   IMyService _myService; 

   public MyClass(IMyService myService)
   {
      _myService = myService;    
   }
}

Ohne IoC, Ihre Klasse, die auf der IMyService beruht muss neu auf eine konkrete Version des Service zu nutzen. Und das ist schlecht für eine Reihe von Gründen (Sie haben Ihre Klasse auf eine bestimmte konkrete Version des IMyService gekoppelt ist, können Sie das Gerät nicht testen leicht, man kann es nicht leicht ändern, usw.)

Mit einem IoC-Container Sie „konfigurieren“ die Container diese Abhängigkeiten für Sie zu lösen. So mit einem Konstruktor-basierten Injektionsschema, übergeben Sie nur die Schnittstelle zur IMyService Abhängigkeit in den Konstruktor. Wenn Sie die MyClass mit Ihrem Container erstellen, wird Ihr Container die IMyService Abhängigkeit für Sie lösen.

Mit StructureMap, die Konfiguration des Behälters sieht wie folgt aus:

StructureMapConfiguration.ForRequestedType<MyClass>().TheDefaultIsConcreteType<MyClass>();
StructureMapConfiguration.ForRequestedType<IMyService>().TheDefaultIsConcreteType<SomeConcreteService>();

Also, was du getan hast gesagt wird, um den Behälter, „Wenn jemand die IMyService anfordert, gibt ihnen eine Kopie des SomeConcreteService.“ Und Sie haben auch festgelegt, dass, wenn jemand für eine MyClass fragt sie einen konkreten MyClass bekommen.

Das ist alles ein IoC-Container wirklich tut. Sie können mehr tun, aber das ist der Schub davon - sie lösen Abhängigkeiten für Sie, so dass Sie nicht zu tun haben (und Sie müssen nicht die „neue“ Schlüsselwort in Ihrem Code verwenden).

Letzter Schritt: Wenn Sie Ihre MyClass erstellen, würden Sie dies tun:

var myClass = ObjectFactory.GetInstance<MyClass>();

Ich hoffe, das hilft. Fühlen Sie sich frei, um mir eine E-Mail.

Andere Tipps

Ich habe ich gerade die 30 Minuten Unity Dependency Injection IoC Screen von David Hayden und fühlte, dass eine gute explaination mit Beispielen war. Hier ist ein Ausschnitt aus der Show Anmerkungen:

Die Screencasts zeigen mehr gemeinsamen Verwendungen der Unity IoC, wie zum Beispiel:

  • Typen nicht in Container anlegen
  • Registrieren und Auflösen von TypeMappings
  • Registrieren und Auflösen von Named TypeMappings
  • Singletons, LifetimeManagers und die ContainerControlledLifetimeManager
  • Registrieren von vorhandenen Instanzen
  • Injizieren von Abhängigkeiten in vorhandene Instanzen
  • Füllen der UnityContainer über App.config / Web.config
  • Festlegen Abhängigkeiten über Injection-API zu Abhängigkeit gegen Attribute
  • Verwenden von Nested (Parent-Child) Container

Einheit ist eine Bibliothek, wie viele andere, dass Sie, ohne dass eine Instanz eines angeforderten Typs erhalten kann es selbst zu erstellen. So gegeben.

public interface ICalculator
{
    void Add(int a, int b);
}

public class Calculator : ICalculator
{
    public void Add(int a, int b)
    {
        return a + b;
    }
}

Sie würden eine Bibliothek wie Unity verwenden Rechner registrieren zurückgegeben werden, wenn der Typ ICalculator angefordert wird aka IoC (Inversion of Control) (in diesem Beispiel theoretisch, technisch nicht korrekt ist).

IoCLlibrary.Register<ICalculator>.Return<Calculator>();

So, jetzt, wenn Sie wollen, eine Instanz eines ICalculator Sie nur ...

Calculator calc = IoCLibrary.Resolve<ICalculator>();

IoC-Bibliotheken können in der Regel so konfiguriert werden, um entweder einen Singleton halten oder eine neue Instanz Sie eine Art lösen jedes Mal erstellen.

Lassen Sie uns jetzt sagen, Sie eine Klasse, die auf einem ICalculator beruht anwesend zu sein könnten Sie haben ..

public class BankingSystem
{
    public BankingSystem(ICalculator calc)
    {
        _calc = calc;
    }

    private ICalculator _calc;
}

Und Sie können die Bibliothek Setup ein Objekt in den Konstruktor zu injizieren, wenn es erstellt.

So DI oder Dependency Injection bedeutet, jedes Objekt zu injizieren, andere erfordern.

Dieser Kerl WilcoxTutorials gibt eine hervorragende Demonstration der Einheit Container, der an Anfänger richtet.

Teil 1: http://www.youtube.com/watch?v=CWwe9Z0Gyew

Teil 2: http://www.youtube.com/watch?v=PsIbevgzQQE

In weniger als einer halben Stunde, und Sie werden die Grundlagen verstehen!

Einheit ist ein IoC. Der Punkt der IoC ist zu abstrahieren die Verdrahtung von Abhängigkeiten zwischen verschiedenen Arten außerhalb der Typen selbst. Dies hat eine Reihe von Vorteilen. Zunächst einmal ist es getan zentral was bedeutet, Sie müssen nicht viel Code ändern, wenn Abhängigkeiten ändern (was der Fall für Unit-Tests sein kann).

Wenn darüber hinaus die Verkabelung statt Code Konfigurationsdaten erfolgen, können Sie tatsächlich die Abhängigkeiten nach der Bereitstellung neu verkabeln und damit das Verhalten der Anwendung ändern, ohne den Code zu ändern.

MSDN hat ein Entwicklerhandbuch zu Dependency Injection Unity Mit dass kann nützlich sein.

Der Leitfaden beginnt Developer mit den Grundlagen dessen, was Dependency Injection ist, und weiterhin mit Beispielen, wie für Dependency Injection Einheit zu verwenden. Ab dem Februar 2014 Entwicklerhandbuch deckt Unity 3.0, die im April 2013 veröffentlicht wurde.

Ich bin für die meisten der Beispiele für Dependency Injection in ASP.NET Web API 2

public interface IShape
{
    string Name { get; set; }
}

public class NoShape : IShape
{
    public string Name { get; set; } = "I have No Shape";
}

public class Circle : IShape
{
    public string Name { get; set; } = "Circle";
}

public class Rectangle : IShape
{
    public Rectangle(string name)
    {
        this.Name = name;
    }

    public string Name { get; set; } = "Rectangle";
}

In DIAutoV2Controller.cs Auto Injection-Mechanismus wird verwendet,

[RoutePrefix("api/v2/DIAutoExample")]
public class DIAutoV2Controller : ApiController
{
    private string ConstructorInjected;
    private string MethodInjected1;
    private string MethodInjected2;
    private string MethodInjected3;

    [Dependency]
    public IShape NoShape { get; set; }

    [Dependency("Circle")]
    public IShape ShapeCircle { get; set; }

    [Dependency("Rectangle")]
    public IShape ShapeRectangle { get; set; }

    [Dependency("PiValueExample1")]
    public double PiValue { get; set; }

    [InjectionConstructor]
    public DIAutoV2Controller([Dependency("Circle")]IShape shape1, [Dependency("Rectangle")]IShape shape2, IShape shape3)
    {
        this.ConstructorInjected = shape1.Name + " & " + shape2.Name + " & " + shape3.Name;
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize()
    {
        this.MethodInjected1 = "Default Initialize done";
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize2([Dependency("Circle")]IShape shape1)
    {
        this.MethodInjected2 = shape1.Name;
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize3(IShape shape1)
    {
        this.MethodInjected3 = shape1.Name;
    }

    [HttpGet]
    [Route("constructorinjection")]
    public string constructorinjection()
    {
        return "Constructor Injected: " + this.ConstructorInjected;
    }

    [HttpGet]
    [Route("GetNoShape")]
    public string GetNoShape()
    {
        return "Property Injected: " + this.NoShape.Name;
    }

    [HttpGet]
    [Route("GetShapeCircle")]
    public string GetShapeCircle()
    {
        return "Property Injected: " + this.ShapeCircle.Name;
    }

    [HttpGet]
    [Route("GetShapeRectangle")]
    public string GetShapeRectangle()
    {
        return "Property Injected: " + this.ShapeRectangle.Name;
    }

    [HttpGet]
    [Route("GetPiValue")]
    public string GetPiValue()
    {
        return "Property Injected: " + this.PiValue;
    }

    [HttpGet]
    [Route("MethodInjected1")]
    public string InjectionMethod1()
    {
        return "Method Injected: " + this.MethodInjected1;
    }

    [HttpGet]
    [Route("MethodInjected2")]
    public string InjectionMethod2()
    {
        return "Method Injected: " + this.MethodInjected2;
    }

    [HttpGet]
    [Route("MethodInjected3")]
    public string InjectionMethod3()
    {
        return "Method Injected: " + this.MethodInjected3;
    }
}

In DIV2Controller.cs wird alles von der Abhängigkeit Konfiguration Resolver Klasse injiziert werden

[RoutePrefix("api/v2/DIExample")]
public class DIV2Controller : ApiController
{
    private string ConstructorInjected;
    private string MethodInjected1;
    private string MethodInjected2;
    public string MyPropertyName { get; set; }
    public double PiValue1 { get; set; }
    public double PiValue2 { get; set; }
    public IShape Shape { get; set; }

    // MethodInjected
    [NonAction]
    public void Initialize()
    {
        this.MethodInjected1 = "Default Initialize done";
    }

    // MethodInjected
    [NonAction]
    public void Initialize2(string myproperty1, IShape shape1, string myproperty2, IShape shape2)
    {
        this.MethodInjected2 = myproperty1 + " & " + shape1.Name + " & " + myproperty2 + " & " + shape2.Name;
    }

    public DIV2Controller(string myproperty1, IShape shape1, string myproperty2, IShape shape2)
    {
        this.ConstructorInjected = myproperty1 + " & " + shape1.Name + " & " + myproperty2 + " & " + shape2.Name;
    }

    [HttpGet]
    [Route("constructorinjection")]
    public string constructorinjection()
    {
        return "Constructor Injected: " + this.ConstructorInjected;
    }

    [HttpGet]
    [Route("PropertyInjected")]
    public string InjectionProperty()
    {
        return "Property Injected: " + this.MyPropertyName;
    }

    [HttpGet]
    [Route("GetPiValue1")]
    public string GetPiValue1()
    {
        return "Property Injected: " + this.PiValue1;
    }

    [HttpGet]
    [Route("GetPiValue2")]
    public string GetPiValue2()
    {
        return "Property Injected: " + this.PiValue2;
    }

    [HttpGet]
    [Route("GetShape")]
    public string GetShape()
    {
        return "Property Injected: " + this.Shape.Name;
    }

    [HttpGet]
    [Route("MethodInjected1")]
    public string InjectionMethod1()
    {
        return "Method Injected: " + this.MethodInjected1;
    }

    [HttpGet]
    [Route("MethodInjected2")]
    public string InjectionMethod2()
    {
        return "Method Injected: " + this.MethodInjected2;
    }
}

Konfigurieren des Abhängigkeitsauflöser

public static void Register(HttpConfiguration config)
{
    var container = new UnityContainer();
    RegisterInterfaces(container);
    config.DependencyResolver = new UnityResolver(container);

    // Other Web API configuration not shown.
}

private static void RegisterInterfaces(UnityContainer container)
{
    var dbContext = new SchoolDbContext();
    // Registration with constructor injection
    container.RegisterType<IStudentRepository, StudentRepository>(new InjectionConstructor(dbContext));
    container.RegisterType<ICourseRepository, CourseRepository>(new InjectionConstructor(dbContext));

    // Set constant/default value of Pi = 3.141 
    container.RegisterInstance<double>("PiValueExample1", 3.141);
    container.RegisterInstance<double>("PiValueExample2", 3.14);

    // without a name
    container.RegisterInstance<IShape>(new NoShape());

    // with circle name
    container.RegisterType<IShape, Circle>("Circle", new InjectionProperty("Name", "I am Circle"));

    // with rectangle name
    container.RegisterType<IShape, Rectangle>("Rectangle", new InjectionConstructor("I am Rectangle"));

    // Complex type like Constructor, Property and method injection
    container.RegisterType<DIV2Controller, DIV2Controller>(
        new InjectionConstructor("Constructor Value1", container.Resolve<IShape>("Circle"), "Constructor Value2", container.Resolve<IShape>()),
        new InjectionMethod("Initialize"),
        new InjectionMethod("Initialize2", "Value1", container.Resolve<IShape>("Circle"), "Value2", container.Resolve<IShape>()),
        new InjectionProperty("MyPropertyName", "Property Value"),
        new InjectionProperty("PiValue1", container.Resolve<double>("PiValueExample1")),
        new InjectionProperty("Shape", container.Resolve<IShape>("Rectangle")),
        new InjectionProperty("PiValue2", container.Resolve<double>("PiValueExample2")));
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top