سؤال

لقد تم قراءة المقالات على MSDN عن الوحدة (حقن التبعية, انعكاس السيطرة) ، ولكن أعتقد أنني بحاجة وأوضح بعبارات بسيطة (أو أمثلة بسيطة).أنا على دراية MVPC نمط (نستخدم هنا), ولكن أنا فقط لا يمكن حقا فهم هذه الوحدة شيء حتى الآن, و أعتقد أنها الخطوة التالية في تصميم التطبيق.

هل كانت مفيدة؟

المحلول

والوحدة هي مجرد اللجنة الاولمبية الدولية "حاوية". جوجل StructureMap ومحاولة الخروج منها بدلا من ذلك. وهناك القليل من الأسهل جروك، كما أعتقد، عندما الاشياء اللجنة الاولمبية الدولية هو جديد لك.

والأساس، وإذا فهمت اللجنة الاولمبية الدولية ثم عليك أن تدرك أن ما تفعلونه هو عكس سيطرة لأنه عندما يحصل على إنشاء كائن.

ودون اللجنة الاولمبية الدولية:

public class MyClass
{
   IMyService _myService; 

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

ومع حاوية اللجنة الاولمبية الدولية:

public class MyClass
{
   IMyService _myService; 

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

ودون اللجنة الاولمبية الدولية، صفك التي تعتمد على IMyService أن الجديد المتابعة نسخة ملموس من الخدمة لاستخدام. وهذا أمر سيء لعدد من الأسباب (كنت قد يقترن صفك إلى إصدار ملموسة محددة من IMyService، لا يمكنك اختبار وحدة بسهولة، لا يمكن تغييره بسهولة، الخ.)

ومع حاوية اللجنة الاولمبية الدولية التي "تكوين" الحاوية لحل تلك التبعيات بالنسبة لك. حتى مع نظام حقن القائم على منشئ، كنت مجرد تمرير واجهة إلى الاعتماد IMyService إلى المنشئ. عند إنشاء MyClass مع الحاويات الخاصة بك، سوف الحاويات حل الاعتماد IMyService بالنسبة لك.

وعن طريق StructureMap، تكوين الحاوية يبدو مثل هذا:

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

وهكذا ما قمت به هو قال الحاوية، "عندما يطلب شخص ما IMyService، ومنحهم نسخة من SomeConcreteService". وقد حددت أيضا أنه عندما يسأل شخص ما لMyClass، فإنهم يحصلون على MyClass ملموسة.

وهذا هو كل وعاء اللجنة الاولمبية الدولية هل حقا. ويمكن أن تفعل أكثر من ذلك، ولكن هذا هو فحوى ذلك - أنها حل تبعيات بالنسبة لك، لذلك لم يكن لديك ل(وأنت ليس لديك لاستخدام "الجديدة" الكلمة طوال التعليمات البرمجية).

والخطوة النهائية: عند إنشاء MyClass الخاصة بك، عليك أن تفعل هذا:

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

وعلى أمل أن يساعد. لا تتردد في الكتابة لي.

نصائح أخرى

أنا فقط شاهدت 30 دقيقة وحدة حقن التبعية الأولمبية الدولية سكرينكست ديفيد هايدن ورأى أنه كان جيد كسبلايناتيون مع الأمثلة.هنا مقتطف من العرض notes:

سكرينكست معارض مشتركة عديدة الأعراف وحدة الأولمبية الدولية ، مثل:

  • إنشاء أنواع لا في الحاوية
  • تسجيل وحل TypeMappings
  • تسجيل وحل اسمه TypeMappings
  • ووحدانية, LifetimeManagers ، ContainerControlledLifetimeManager
  • تسجيل القائمة الحالات
  • حقن التبعيات الموجودة الحالات
  • ملء UnityContainer عبر التطبيق.config / ويب.التكوين
  • تحديد تبعيات طريق الحقن API بدلا من الاعتماد على سمات
  • باستخدام متداخلة ( الأم والطفل ) حاويات

والوحدة هي مكتبة مثل كثيرين آخرين أن تسمح لك الحصول على مثيل من نوع المطلوبة دون الحاجة إلى إنشاء ذلك بنفسك. لذا معين.

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

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

ويمكنك أن استخدام مكتبة مثل الوحدة لتسجيل حاسبة يتم إرجاعها عند طلب نوع ICalculator ويعرف أيضا باسم اللجنة الاولمبية الدولية (عكس من التحكم) (هذا المثال النظري، وليس من الناحية الفنية الصحيح).

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

وحتى الآن عندما تريد مثيل ICalculator أنت فقط ...

Calculator calc = IoCLibrary.Resolve<ICalculator>();
يمكن عادة أن يتم تكوين

والمكتبات اللجنة الاولمبية الدولية إما عقد المفرد أو إنشاء مثيل جديد في كل مرة تقوم بحل نوع.

والآن دعونا نقول لديك فئة التي تعتمد على ICalculator أن يكون حاضرا هل يمكن أن يكون ..

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

    private ICalculator _calc;
}

ويمكنك إعداد مكتبة لحقن كائن في منشئ عند إنشائه.

وهكذا DI أو التبعية حقن يعني ضخ أي وجوه قد تتطلب آخر.

وهذا WilcoxTutorials الرجل يعطي دليلا ممتازا للحاوية الوحدة التي تهدف الى مبتدئين.

الجزء 1: http://www.youtube.com/watch؟v=CWwe9Z0Gyew

والجزء 2: http://www.youtube.com/watch؟v=PsIbevgzQQE

في أقل من نصف ساعة وسوف تفهم أساسيات!

والوحدة هي اللجنة الاولمبية الدولية. نقطة من اللجنة الاولمبية الدولية هي مجردة الأسلاك تبعيات بين أنواع خارج أنواع أنفسهم. هذا وقد اثنين من المزايا. أولا وقبل كل شيء، ويتم مركزيا مما يعني أنك لا تضطر إلى تغيير الكثير من التعليمات البرمجية عندما تتغير تبعيات (الذي قد يكون صحيحا بالنسبة للاختبارات وحدة).

وعلاوة على ذلك، إذا تم الأسلاك باستخدام بيانات التكوين بدلا من التعليمات البرمجية، يمكنك فعلا تركيب شبكة كهرباء جديدة التبعيات بعد النشر، وبالتالي تغيير السلوك من التطبيق دون تغيير التعليمات البرمجية.

وMSDN لديه المطور دليل على التبعية حقن عن طريق الوحدة التي قد كن مفيدا.

ودليل المطور ليبدأ مع أساسيات ما هو الاعتماد على الحقن، وتواصل مع أمثلة على كيفية استخدام الوحدة من أجل حقن التبعية. اعتبارا من عام 2014 فبراير يغطي دليل المطور الوحدة 3.0، والذي صدر في أبريل 2013.

وأنا تغطي معظم الأمثلة من التبعية حقن في API ويب ASP.NET 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";
}

في DIAutoV2Controller.cs يستخدم آلية حقن السيارات

[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;
    }
}

في DIV2Controller.cs سيتم حقن كل شيء من الطبقة التبعية تكوين محلل

[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;
    }
}

وتكوين التبعية محلل

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")));
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top