কেউ কি মাইক্রোসফ্ট ইউনিটির ব্যাখ্যা দিতে পারেন?


157

আমি ইউনিটি (ডিপেন্ডেন্সি ইনজেকশন, নিয়ন্ত্রণের বিপরীতমুখী) সম্পর্কে এমএসডিএন-এর নিবন্ধগুলি পড়ছি, তবে আমি মনে করি এটি সহজ শর্তে (বা সাধারণ উদাহরণ) ব্যাখ্যা করার দরকার আছে। আমি এমভিপিসি প্যাটার্নের সাথে পরিচিত (আমরা এটি এখানে ব্যবহার করি) তবে আমি এখনও এই ইউনিটির জিনিসটি এখনও বুঝতে পারি না এবং আমি মনে করি এটি আমাদের অ্যাপ্লিকেশন ডিজাইনের পরবর্তী পদক্ষেপ।


12
আমি পছন্দ করি এটি কীভাবে "ইউনিটি" এর একই নাম রয়েছে তাই যখন আমি ইউনিটি গেম ইঞ্জিনের জিনিসগুলি অনুসন্ধান করি তখন আমি এই পুরানো প্রযুক্তিটি দেখি, দীর্ঘশ্বাস ফেললাম। সমস্ত ভাল ব্যান্ডের নাম নেওয়া হয়েছে, আমি অনুমান।
টম শুলজ

2
@ টম-স্কুলজ ওল্ড টেক? nuget.org/packages/Unity - সর্বশেষ আপডেট হয়েছে 5 দিন আগে।
রজার উইলককস

উত্তর:


174

Ityক্য হ'ল একটি আইওসি "ধারক"। গুগল স্ট্রাকচারম্যাপ এবং এর পরিবর্তে এটি ব্যবহার করে দেখুন। আমি মনে করি, যখন আইওসি স্টাফগুলি আপনার কাছে নতুন।

মূলত, আপনি যদি আইওসি বুঝতে পারেন তবে আপনি বুঝতে পারেন যে আপনি যখন করছেন তখন কোনও বস্তু তৈরি হওয়ার জন্য নিয়ন্ত্রণটি উল্টে দিচ্ছে।

আইওসি ছাড়াই:

public class MyClass
{
   IMyService _myService; 

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

আইওসি ধারক সহ:

public class MyClass
{
   IMyService _myService; 

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

আইওসি ছাড়াই, আপনার ক্লাস যা আইএমই সার্ভিসের উপর নির্ভর করে সেগুলি পরিষেবাটির একটি কংক্রিট সংস্করণ নতুন করে আপ করতে হবে up এবং এটি বেশ কয়েকটি কারণে খারাপ (আপনি নিজের ক্লাসটি আইএমওয়াই সার্ভিসের একটি নির্দিষ্ট কংক্রিট সংস্করণে মিলিয়েছেন, আপনি সহজেই এটি পরীক্ষা করতে পারবেন না, আপনি এটি সহজে পরিবর্তন করতে পারবেন না ইত্যাদি)

কোনও আইওসি পাত্রে আপনার নিজের জন্য সেই নির্ভরতাগুলি সমাধান করার জন্য আপনি ধারকটি "কনফিগার" করুন। সুতরাং কনস্ট্রাক্টর-ভিত্তিক ইনজেকশন স্কিমের সাহায্যে আপনি কেবল ইন্টারফেসটি আইএমওয়াই সার্ভিস নির্ভরতাতে কনস্ট্রাক্টরের মধ্যে দিয়ে যান। আপনি যখন আপনার ধারকটির সাথে মাইক্লাস তৈরি করবেন তখন আপনার ধারক আপনার জন্য আইএমই সার্ভিস নির্ভরতা সমাধান করবে।

স্ট্রাকচারম্যাপ ব্যবহার করে কনটেইনারটি কনফিগার করে এমন দেখাচ্ছে:

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

সুতরাং আপনি যা করেছেন তা ধারকটিকে বলা হয়েছে, "যখন কেউ আইএমই সার্ভিসেসের জন্য অনুরোধ করে, তখন তাদেরকে সোমারসেক্রেটস সার্ভিসের একটি অনুলিপি দিন।" এবং আপনি এটিও নির্দিষ্ট করেছেন যে কেউ যখন মাইক্লাসের জন্য জিজ্ঞাসা করেন, তারা একটি কংক্রিট মাইক্লাস পান।

এটি একটি আইওসি পাত্রে সত্যই করে। তারা আরও কিছু করতে পারে, তবে এটিই এর জোর - তারা আপনার জন্য নির্ভরতা সমাধান করে, তাই আপনাকে করতে হবে না (এবং আপনার কোড জুড়ে আপনাকে "নতুন" কীওয়ার্ডটি ব্যবহার করতে হবে না)।

চূড়ান্ত পদক্ষেপ: আপনি যখন নিজের মাই ক্লাস তৈরি করবেন, আপনি এটি করবেন:

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

আশা করি এইটি কাজ করবে. নির্দ্বিধায় আমাকে ই - মেইল ​​কর.


2
সুতরাং এটি একটি কারখানার মতো, আমি মনে করি? যদি আমি এটি সঠিকভাবে অনুসরণ করি তবে আপনি কি চূড়ান্ত উদাহরণে <মাইক্ল্যাস> এর পরিবর্তে <আইএমইক্ল্যাটিস> ব্যবহার করবেন না? সুতরাং এটি var myClass = অবজেক্টফ্যাক্টরি হবে et আপনার সহায়তার জন্য ধন্যবাদ, এটি আমার জন্য একটি ভাল শুরু!
রায়ান অ্যাবট

3
একরকম, এটি কারখানার মতো, হ্যাঁ। আপনার আবেদনের জন্য একটি মাস্টার কারখানা। তবে এটি সিলেটলেট সহ বিভিন্ন ধরণের প্রচুর ফেরত কনফিগার করা যেতে পারে। মাইক্লাসের ইন্টারফেসের জন্য - এটি যদি কোনও ব্যবসায়িক অবজেক্ট হয় তবে আমি কোনও ইন্টারফেস বের করব না। অন্য সব কিছুর জন্য, আমি সাধারণত।
ক্রিস হোমস

আপনি যদি কেবলমাত্র অবজেক্টফ্যাক্টরি বলে থাকেন etGETInstance <MyClass> (); এবং আপনি সোমারক্রিটক্র্লাসটি কনফিগার করেননি? সেক্ষেত্রে আপনি কি ত্রুটি পাবেন?
রায়লাভলেস

1
@ রায়: এটি পাত্রে নির্ভর করে। কিছু পাত্রে এমনভাবে লেখা থাকে যাতে, ডিফল্টরূপে তারা একটি নামকরণের কনভেনশন ব্যবহার করে, যেমন কোনও শ্রেণীর নাম মাইক্লাস এবং ইন্টারফেসটির নাম দেওয়া হয় আইএমআইইন্টারফেস, কনটেইনারটি স্বয়ংক্রিয়ভাবে সেই শ্রেণিটি ইন্টারফেসের জন্য কনফিগার করে। সুতরাং সেই ক্ষেত্রে, আপনি যদি এটি ম্যানুয়ালি কনফিগার না করেন তবে কনটেইনারটির ডিফল্ট "কনভেনশন" এটিকে যাইহোক আপ করে তোলে। তবে, যদি আপনার শ্রেণি এবং ইন্টারফেস কনভেনশন অনুসরণ না করে এবং আপনি সেই শ্রেণীর জন্য ধারকটি কনফিগার না করেন, তবে হ্যাঁ, রানটাইমে আপনি একটি ত্রুটি পান।
ক্রিস হোমস

1
@ সরভানান আমি মনে করি স্ট্রাকচারম্যাপ এখন একটি নাম ভিত্তিক কনভেনশন করে। আমি নিশ্চিত নই; আমরা এটি দীর্ঘ সময় ব্যবহার করি নি (আমি আমাদের ব্যবসায়ের জন্য একটি কাস্টম লিখেছি; এটি ইন্টারফেস এবং ক্লাসগুলির জন্য একই নামের কনভেনশন ব্যবহার করে)।
ক্রিস হোমস

39

আমি স্রেফ ডেভিড হেডেনের 30 মিনিটের ইউনিটি নির্ভরতা ইনজেকশন আইওসি স্ক্রিনকাস্ট দেখেছি এবং অনুভব করেছি যে উদাহরণগুলির সাথে এটি একটি ভাল ব্যাখ্যা। শো নোটগুলির একটি স্নিপেট এখানে রয়েছে:

স্ক্রিনকাস্টটি ইউনিটি আইওসির কয়েকটি সাধারণ ব্যবহার দেখায়, যেমন:

  • ধারক না করে প্রকার তৈরি করা হচ্ছে
  • টাইপম্যাপিংগুলি নিবন্ধকরণ এবং সমাধান করছেন
  • নামযুক্ত টাইপম্যাপিংগুলি নিবন্ধকরণ এবং সমাধান করা
  • সিলেটলেটস, লাইফটাইম ম্যানেজারস এবং কনটেইনারকন্ট্রোলড লাইফটাইম ম্যানেজার
  • বিদ্যমান উদাহরণ নিবন্ধন করা
  • বিদ্যমান উদাহরণগুলিতে নির্ভরতা ইনজেকশন করা
  • অ্যাপকনফিগ / ওয়েবকনফিগের মাধ্যমে ইউনিটি কনটেনার স্থাপন করা
  • নির্ভরতা বৈশিষ্ট্যের বিপরীতে ইনজেকশন এপিআইয়ের মাধ্যমে নির্ভরতা নির্দিষ্ট করে
  • নেস্টেড (প্যারেন্ট-চাইল্ড) কনটেইনার ব্যবহার করা

32

Ityক্য হ'ল অনেকগুলি লাইব্রেরি যা আপনাকে নিজে তৈরি না করেই কোনও অনুরোধের ধরণের উদাহরণ পেতে দেয়। তাই দেওয়া হয়েছে।

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

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

ক্যালকুলেটরটি ফেরত পাঠানোর জন্য আপনি ইউনিটির মতো একটি লাইব্রেরি ব্যবহার করবেন যখন আইসিএলকুলেটর টাইপ করা হয় ওরফে আইওসি (নিয়ন্ত্রণের বিপরীতমুখী) অনুরোধ করা হয় (এই উদাহরণটি তাত্ত্বিক, প্রযুক্তিগতভাবে সঠিক নয়)।

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

সুতরাং এখন আপনি যখন একটি আইক্য্যালকুলেটর একটি উদাহরণ চান আপনি ঠিক ...

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

আইওসি লাইব্রেরিগুলি সাধারণত কোনও সিঙ্গলটন ধারণ করতে কনফিগার করা যায় বা আপনি যখনই কোনও প্রকারের সমাধান করেন তখনই একটি নতুন ইভেন্ট তৈরি করতে পারেন।

এখন ধরা যাক আপনার কাছে এমন একটি শ্রেণি রয়েছে যা উপস্থিত থাকতে আইক্যালকুলেটরের উপর নির্ভর করে ..

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

    private ICalculator _calc;
}

এবং আপনি লাইব্রেরিটি তৈরি করতে গেলে কনস্ট্রাক্টরের মধ্যে কোনও বস্তু ইনজেকশনের জন্য সেটআপ করতে পারেন।

সুতরাং ডিআই বা ডিপেন্ডেন্সি ইনজেকশন মানে অন্য যে কোনও বস্তুর ইনজেকশন লাগতে পারে in


আইসিএলকুলেটর ক্যালক হওয়া উচিত = আইওসিলেব্রি. সমাধান করুন <আই ক্যালকুলেটর> ();
শুক্রত রায়মভ

31

এই লোকটি উইলকক্স টিউটোরিয়ালগুলি ইউনিটির ধারকটির একটি দুর্দান্ত প্রদর্শন দেয় যা শুরুতে লক্ষ্য করা যায়।

পর্ব 1: http://www.youtube.com/watch?v=CWwe9Z0Gyew

পর্ব 2: http://www.youtube.com/watch?v=PsIbevgzQQE

আধঘন্টারও কম সময়ের মধ্যে এবং আপনি বেসিকগুলি বুঝতে পারবেন!


3
এগুলি সত্যিই সহায়ক
ভিডিস

10

Ityক্য একটি আইওসি। আইওসির মূল বিষয়টি হ'ল ধরণের বাইরের ধরণের মধ্যে নির্ভরতার ওয়্যারিং বিমূর্ত করা। এর বেশ কয়েকটি সুবিধা রয়েছে। প্রথমত, এটি কেন্দ্রীয়ভাবে করা হয় যার অর্থ নির্ভরতা পরিবর্তনের সময় আপনাকে প্রচুর কোড পরিবর্তন করতে হবে না (যা ইউনিট পরীক্ষার ক্ষেত্রে হতে পারে)।

তদুপরি, যদি তারের কোডের পরিবর্তে কনফিগারেশন ডেটা ব্যবহার করে করা হয়, আপনি আসলে স্থাপনার পরে নির্ভরতাগুলি পুনর্বিবেচনা করতে পারেন এবং এইভাবে কোডটি পরিবর্তন না করে অ্যাপ্লিকেশনটির আচরণ পরিবর্তন করতে পারেন।


5

এমএসডিএন এর সাথে ডেভেলপারদের Depক্য ব্যবহার করে নির্ভরতা ইনজেকশন সম্পর্কিত গাইড রয়েছে যা দরকারী হতে পারে।

বিকাশকারীদের গাইডেন্স নির্ভরতা ইনজেকশন কী এর মূল বিষয়গুলি দিয়ে শুরু হয় এবং নির্ভরতা ইঞ্জেকশনের জন্য ইউনিটি কীভাবে ব্যবহার করতে হয় তার উদাহরণ দিয়ে চালিয়ে যায়। ফেব্রুয়ারী ২০১৪ পর্যন্ত বিকাশকারীদের গাইড ইউনিটি 3.0.০ কভার করেছে যা এপ্রিল 2013 এ প্রকাশিত হয়েছিল।


1

আমি এএসপি.নেট ওয়েব এপিআই 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";
}

ডিআইএআউটও 2 কন্ট্রোলার.এস-এ অটো ইনজেকশন প্রক্রিয়া ব্যবহৃত হয়

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

ডিআইভি 2 কন্ট্রোলার.এস-এ ডিপেন্ডেন্সি কনফিগারেশন রিসলভার ক্লাস থেকে সবকিছু ইনজেকশনের ব্যবস্থা করা হবে

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

এটি বেশ কয়েকটি কারণে বিশেষভাবে কার্যকর উত্তর নয়। এটি একটি অপ্রয়োজনীয় জটিল উদাহরণ যা আইওসির একটি সহজ ব্যাখ্যা দেওয়ার ক্ষেত্রে প্রচুর কোড কার্যকর হতে পারে। তদতিরিক্ত, কোডগুলি সেই জায়গাগুলিতে স্পষ্টভাবে নথিভুক্ত করা হয়নি যেখানে আপনার প্রকৃতপক্ষে এটির প্রয়োজন হবে।
ড্যান অ্যাটকিনসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.