سؤال

أنا أستخدم وحدة Microsoft لحقن التبعية وأريد أن أفعل شيئا مثل هذا:

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 معلمة، وأريد جمعية تهيئة المستودع مع السياق الذي اجتيازه. لاحظ أيضا ذلك IDataContext غير مسجل بالوحدة (لا أريد 3 مثيلات IDataContext).

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

المحلول

اعتبارا من اليوم، أضافوا هذه الوظيفة:

إنه في أحدث قطرة هنا:

http://unity.codeplex.com/sourcecontrol/changeset/view/33899.

مناقشة حولها هنا:

http://unity.codeplex.com/thread/view.aspx؟threadid=66434.

مثال:

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

نصائح أخرى

<2 سنتات>

ماذا لو كنت في وقت لاحق تقرر استخدام خدمة مختلفة تتطلب أكثر أو أقل من السياق فقط؟

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

سيكون اقتراحي هو إما أن يحل السياق أيضا، وأعتقد أن الوحدة يجب أن يكون لديك وسيلة لك لتجنب بناء 3 مثيلات منه، أو يجب أن تنظر في خدمة المصنع لديها وسيلة لك لبناء الكائن.

على سبيل المثال، ماذا لو كنت في وقت لاحق تقرر إنشاء مستودع لا يعتمد على قاعدة بيانات تقليدية على الإطلاق، ولكن بدلا من استخدام ملف XML لإنتاج بيانات دمية لاختبار؟ كيف يمكنك الذهاب حول تغذية محتوى XML لهذا المنشئ؟

يعتمد IOC حول رمز فك، من خلال ربطه في النوع والدوائر في الحجج إلى الأنواع الخرسانية، أنت حقا لم تقدم فصل بشكل صحيح، لا يزال هناك اعتماد.

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

الآن، أعرف أن حاويات IOC الأخرى لديها دعم لهذا، وكان لي في أول إصداري من بلدي أيضا، ولكن في رأيي، لا ينتمي إلى خطوة القرار.

</ 2 سنتات>

شكرا يا رفاق ... من مشابه للنشر عن طريق "موجود". انظر أدناه:

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

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

يمكنك استخدام الحقن / حقن Ropection / InjectionMethod اعتمادا على بنية الحقن الخاصة بك ضمن requadpedparameter <t> ("الاسم" ("الاسم") للحصول على مثيل كائن مسجل مسبقا في الحاوية.

في حالتك، يجب تسجيل هذا الكائن باسم، وللما نفس الإسكان الذي تحتاجه عبر CercisontrolleDliFetimemanager () ك Lifetimemanager.

_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")));

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

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

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

بديل آخر يمكنك استخدامه (لا أعرف حقا ما إذا كانت ممارسات جيدة أم لا) إنشاء حاوية اثنين وتسجيل مثيل لكل منها:

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

آمل أن يساعد هذا أيضا

Notdan، أعتقد أنك ربما أجبت على سؤالك الخاص في تعليقات Lassevk.

أولا، أود استخدام LifetImemanager لإدارة دورة حياة وعدد مثيلات idatacontext التي تنشئ الوحدة.
http://msdn.microsoft.com/en-us/library/cc440953.aspx.

يبدو وكأنه ContainerControlledLifetimeManager سوف يمنحك الكائن إدارة المثيل الذي تحتاجه. مع هذا LifetImemanager في المكان، يجب أن تضيف الوحدة نفس مثيل idatacontext إلى جميع الكائنات التي تتطلب تبعية idatacontext.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top