আমি কি ইউনিটির সমাধান () পদ্ধতিতে কনস্ট্রাক্টর পরামিতিগুলি পাস করতে পারি?


92

আমি নির্ভরতা ইনজেকশনের জন্য মাইক্রোসফ্টের Unক্য ব্যবহার করছি এবং আমি এরকম কিছু করতে চাই:

IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context

IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);

RepositoryAএবং RepositoryBউভয়ের কাছে একটি কনস্ট্রাক্টর রয়েছে যা একটি IDataContextপ্যারামিটার নেয় এবং আমি চাই ইউনিটি Iক্যটি আমার যে প্রসঙ্গে প্রাসঙ্গিকভাবে প্রাসঙ্গিক তা পাস করে প্রবর্তনটি আরম্ভ করতে পারে। এছাড়াও লক্ষ করুন যে IDataContextইউনিটির সাথে নিবন্ধিত নয় (আমি 3 টি উদাহরণ চাই না IDataContext)।

উত্তর:


71

আজ অবধি তারা এই কার্যকারিতা যুক্ত করেছে:

এটি এখানে সর্বশেষ ড্রপ মধ্যে:

http://une.codeplex.com/SourceControl/changeset/view/33899

এখানে এটি নিয়ে আলোচনা:

http://une.codeplex.com/Thread/View.aspx?ThreadId=66434

উদাহরণ:

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"



4
"ক্লাস 'মাইক্রোসফ্ট.প্র্যাকটিসস. ইউনিটি.প্যারামিটার ওভারাইডস'র টাইপ প্যারামিটার নেই। আমি ইউনিটি 3.5 ব্যবহার করছি; এই কোডটি কি কেবল ইউনিটির পুরানো সংস্করণের জন্য বৈধ?
টমাস লেভেস্ক

এটা আমার জন্য কাজ করে. দ্রষ্টব্য: আপনার শ্রেণিতে অবশ্যই "নাম" প্যারামিটার এবং "ঠিকানা" পরামিতি সহ একটি প্যারামাইট্রাইজড কনস্ট্রাক্টর থাকতে হবে। Foo(string name, int address) { ... }
adun

container.Resolve<IFoo>(new ParameterOverrides { { "name", "bar" }, { "address", 42 } });
Ityক্যটি

38

<2 সেন্ট>

আপনি যদি পরে কোনও পৃথক পরিষেবা ব্যবহারের সিদ্ধান্ত নেন যা কেবল প্রসঙ্গের চেয়ে কম বা কম প্রয়োজন?

কনস্ট্রাক্টর প্যারামিটার এবং আইওসির সমস্যাটি হ'ল প্যারামিটারগুলি পরিশেষে ব্যবহার করা কংক্রিটের ধরণের সাথে বেঁধে দেওয়া হয়, পরিষেবার ইন্টারফেসের দ্বারা সংজ্ঞায়িত চুক্তির অংশ হওয়ার বিপরীতে।

আমার পরামর্শটি হ'ল আপনি হয় প্রসঙ্গটিও সমাধান করুন এবং আমি বিশ্বাস করি যে ityক্যের পক্ষে এটির 3 টি উদাহরণ তৈরি করা এড়াতে আপনার পক্ষে একটি উপায় থাকা উচিত, অথবা আপনি কোনও কারখানার পরিষেবাটি বিবেচনা করা উচিত যাতে আপনার অবজেক্টটি তৈরির উপায় রয়েছে।

উদাহরণস্বরূপ, আপনি যদি পরে কোনও osতিহ্যবাহী ডাটাবেসের উপর নির্ভর করে না এমন একটি সংগ্রহশালা নির্মাণের সিদ্ধান্ত নেন, তবে পরিবর্তে পরীক্ষার জন্য ডামি-ডেটা তৈরি করতে একটি এক্সএমএল ফাইল ব্যবহার করেন? আপনি কীভাবে সেই কনস্ট্রাক্টরকে এক্সএমএল সামগ্রী সরবরাহ করতে যাবেন?

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

"এই কোডটি যেকোন প্রকারের সংগ্রহস্থলের সাথে সম্ভবত কথা বলতে পারে, যতক্ষণ না এটি এই ইন্টারফেসটি প্রয়োগ করে .... ওহ, এবং ডেটা প্রসঙ্গ ব্যবহার করে"।

এখন, আমি জানি যে অন্যান্য আইওসি পাত্রে এটির জন্য সমর্থন রয়েছে এবং এটি আমার নিজের প্রথম সংস্করণেও ছিল, তবে আমার মতে, এটি রেজোলিউশন পদক্ষেপের সাথে সম্পর্কিত নয়।

</ 2 সেন্ট>


4
আমি আপনার বক্তব্যটি দেখছি এবং আপনার সাথে একমত হয়েছি, তবে এখনও আমার কাছে একই আইডাটা কনটেক্সট থাকতে RepositoryA এবং RepositoryB এর দৃষ্টান্ত প্রয়োজন, যা RepositoryC এর চেয়ে আলাদা হওয়া দরকার। এছাড়াও নোট করুন যে আইআরপোসিটোরিএ এবং আইআরপোসিটোরিবি'র আইডিটা কনটেক্সট-এর জন্য একটি সম্পত্তি রয়েছে। আমি নমুনা কোডটি কিছুটা আপডেট করব।
নোটড্যান

4
দুর্দান্ত পয়েন্ট। আমি কনস্ট্রাক্টরটিতে একটি স্ট্রিং প্যারামিটার যুক্ত করতে চলেছি, তবে এই পয়েন্টটি দেখার পরে, আমি এটিকে একটি সম্পূর্ণ প্রস্ফুটিত বস্তু করার সিদ্ধান্ত নিয়েছি। এটি কেবলমাত্র এই মুহুর্তে স্ট্রিং নিয়ে গঠিত তবে আমি ইতিমধ্যে দেখতে পাচ্ছি যে আমি কীভাবে এটিতে আরও দরকারী বৈশিষ্ট্য যুক্ত করতে পারি
সন্তোষ বেনিয়ামিন

9

ধন্যবাদ ছেলেরা ... আমার "অস্তিত্ব" র পোস্টের মতোই। নিচে দেখ:

        IUnityContainer container = new UnityContainer();
        container.LoadConfiguration();

        _activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
        {
            new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
        });

5

ধারকটিতে প্রাক-নিবন্ধিত অবজেক্টের উদাহরণ পাওয়ার জন্য আপনি রেজোলিউডপ্যারামিটার <টি> ("নাম") এর মধ্যে আপনার ইনজেকশন আর্কিটেকচারের উপর নির্ভর করে ইনজেকশন কনস্ট্রাক্টর / ইনজেকশন প্রপার্টি / ইনজেকশনমিথড ব্যবহার করতে পারেন।

আপনার ক্ষেত্রে এই অবজেক্টটি অবশ্যই একটি নামের সাথে নিবন্ধিত হতে হবে এবং একই বিড়ালের জন্য আপনার লাইফটাইমম্যানেজার হিসাবে কনটেইনারকন্ট্রোলড লাইফটাইমম্যানেজার () দরকার।

_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");

  var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));

4
আপনি এই কোড সম্পর্কে নিশ্চিত? এটি সংকলন করে না ... এর Resolveসংগ্রহ নেয় ResolverOverride, এবং InjectionConstructorহয় না ResolverOverride
টমাস লেভেস্ক

হ্যাঁ এটি ভুল দেখাচ্ছে। যদিও unityক্যের এটি সেইভাবে ডিজাইন করা উচিত ছিল। যদি প্যারামিটারের নাম পরিবর্তন হয় তবে সবকিছু ভেঙে যায়
ফ্র্যাঙ্ক কি।

3

খুব সংক্ষিপ্ত উত্তরটি: না। Ityক্যের কাছে বর্তমানে কনস্ট্রাক্টরের প্যারামিটারগুলি পাস করার কোনও উপায় নেই যা ধ্রুবক বা ইঞ্জেকশনযুক্ত নয়, যা আমি সন্ধান করতে সক্ষম হয়েছি। আইএমএইচও এটি একমাত্র বৃহত্তম জিনিস যা অনুপস্থিত, তবে আমি মনে করি এটি বাদ না দিয়ে ডিজাইনের মাধ্যমে।

জেফ ফ্রিটজ নোট হিসাবে, আপনি তাত্ত্বিকভাবে একটি কাস্টম লাইফ টাইম ম্যানেজার তৈরি করতে পারেন যা জানেন যে কোন প্রসঙ্গটি বিভিন্ন ধরণের ইনজেকশন করতে পারে, তবে এটি কঠোর কোডিংয়ের একটি স্তর যা ইউনিটি বা ডিআই-কে প্রথম স্থানে ব্যবহার করার উদ্দেশ্যকে অবিচ্ছিন্ন বলে মনে হয়।

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


1

আপনি যে বিকল্পটি ব্যবহার করতে পারেন (এটি একটি ভাল অনুশীলন কিনা তা সত্যিই জানেন না) দুটি পাত্রে তৈরি করছে এবং প্রতিটিটির জন্য উদাহরণ নিবন্ধন করছে:

IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context


//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance

আশা করি এটিও সাহায্য করবে


0

নোটড্যান, আমি মনে করি আপনি লাসেভেককে মন্তব্যে আপনার নিজের প্রশ্নের উত্তর দিয়েছেন।

প্রথমত, আমি লাইফটাইম ম্যানেজারটি useক্যবদ্ধতার দ্বারা তৈরি করা IDataContext এর লাইফসাইকেল এবং সংখ্যার উদাহরণ পরিচালনা করতে ব্যবহার করব।
http://msdn.microsoft.com/en-us/library/cc440953.aspx

দেখে মনে হচ্ছে ContainerControlledLifetimeManagerঅবজেক্টটি আপনার প্রয়োজনীয় ইনস্ট্যান্স ম্যানেজমেন্টটি দেবে। সেই লাইফটাইম ম্যানেজারের জায়গায়, ইউনিটির উচিত আইডিটা কনটেক্সট-এর একই উদাহরণটি সমস্ত আইটেমের সাথে যুক্ত করা উচিত যার জন্য একটি আইডিটা কনটেক্সট নির্ভরতা প্রয়োজন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.