واللجنة الأوقيانوغرافية الحكومية الدولية ، Dll المراجع و الجمعية المسح الضوئي

StackOverflow https://stackoverflow.com/questions/809051

سؤال

على الرغم من أن هذا السؤال مرتبط StructureMap ، العامة السؤال هو:

عندما يصل الأسلاك المكونات مع اللجنة الأولمبية الدولية حاوية في التعليمات البرمجية (بدلا من إلى تكوين عبر xml) هل عموما بحاجة صريحة المشروع/بناء إشارات إلى جميع الجمعيات?

لماذا منفصلة الجمعيات?لأن:


"فئات مجردة المقيمين في منفصلة الجمعية من الخرسانة تطبيقات طريقة رائعة تحقيق هذا الفصل." -الإطار المبادئ التوجيهية تصميم الصفحة.91


على سبيل المثال:

دعونا نقول لدي PersonBase.dll و Bob.dll

بوب يرث من فئة مجردة PersonBase.كلاهما في الشخص مساحة الاسم. ولكن في مختلف المجالس.

أنا البرمجة PersonBase, لا بوب.

مرة أخرى في بلدي الرئيسية التعليمات البرمجية, أنا بحاجة شخص.StructureMap يمكن مسح التجمعات.عظيم, أنا أطلب StructureMap واحد!

الآن في رئيسية المدونة ، وأنا بالطبع لا يشير إلا إلى PersonBase, لا أن بوب.في الواقع أنا لا أريد أن تعرف رمز أي شيء عن بوب.لا مراجع المشروع لا nuthin.هذا هو بيت القصيد.

لذلك أريد أن أقول:

//Reference: PersonBase.dll (only)
using Person;  
...

//this is as much as we'll ever be specific about Bob:
Scan( x=> { x.Assembly("Bob.dll"); }

//Ok, I should now have something that's a PersonBase (Bob). But no ?
ObjectFactory.GetAllInstances<PersonBase>().Count == 0

لا حظ.ما العمل يجري الصريحة التي أريد بوب:

//Reference: PersonBase.dll and Bob.dll
using Person; 
...
Scan( x => {x.Assembly("Bob.dll"); }

//If I'm explicit, it works. But Bob's just a PersonBase, what gives?
ObjectFactory.GetAllInstances<Bob>().Count == 1 //there he is!

ولكن الآن يجب أن المرجعية Bob.dll في المشروع الذي هو بالضبط ما كنت لا تريد.

لا يمكن تجنب هذه الحالة باستخدام الربيع + تكوين Xml.ولكن بعد ذلك عدت إلى الربيع + تكوين Xml ...!

أنا في عداد المفقودين شيء مع استخدام StructureMap ، أو العامة ، المبدأ هل (بطلاقة) IoC تكوينات تحتاج explict المراجع إلى جميع الجمعيات?

ربما ذات السؤال: StructureMap والمسح الضوئي الجمعيات

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

المحلول

وأخيرا حصلت هذه المشكلة.يبدو مثل هذا:

اللجنة الاولمبية الدولية Uml http://img396.imageshack.us/img396/1343/iocuml.jpg

مع الجمعيات

  • Core.exe
  • PersonBase.dll (المشار إليها وقت الترجمة قبل Core.exe)
  • Bob.dll (تحميل وقت تشغيل عبر StructureMap Scan)
  • Betty.dll (تحميل وقت تشغيل عبر StructureMap Scan)

للحصول عليه مع StructureMap, أنا في حاجة إلى العرف "ITypeScanner" لدعم المسح على الجمعيات:

public class MyScanner : ITypeScanner {
  public void Process(Type type, PluginGraph graph) {

    if(type.BaseType == null) return;

    if(type.BaseType.Equals(typeof(PersonBase))) {
      graph.Configure(x => 
        x.ForRequestedType<PersonBase>()
        .TheDefault.Is.OfConcreteType(type));
    }
  }
} 

لذا الرئيسية رمز تبدو مثل:

ObjectFactory.Configure(x => x.Scan (
  scan =>
  {
    scan.AssembliesFromPath(Environment.CurrentDirectory 
    /*, filter=>filter.You.Could.Filter.Here*/);

    //scan.WithDefaultConventions(); //doesn't do it

    scan.With<MyScanner>();
  }
));

ObjectFactory.GetAllInstances<PersonBase>()
 .ToList()
  .ForEach(p => 
  { Console.WriteLine(p.FirstName); } );

نصائح أخرى

يمكنك أن تفعل تكوين xml مع StructureMap كذلك.حتى يمكنك مزجها إذا كنت تريد.

هناك أيضا StructureMap سمات كنت قد وضعت في بوب الدرجة أن أقول StructureMap كيفية تحميل الجمعية.DefaultConstructor هو واحد أنا في نهاية المطاف باستخدام من وقت لآخر.

التلقائي المسح الضوئي الخيار يعمل فقط عندما يمكنك الحفاظ على تسمية الجمعية و مساحة الاتفاقيات.يمكنك يدويا تكوين structuremap مع يجيد واجهة.على سبيل المثال:

ObjectFactory.Initialize(initialization => 
   initialization.ForRequestedType<PersonBase>()
    .TheDefault.Is.OfConcreteType<Bob>());

ما نقوم به في مشروعي الحالي (الذي يستخدم AutoFac لا StructureMap ، ولكن أعتقد أنه لا يجب أن تحدث فرقا):

لدينا واجهات تحديد الخدمات الخارجية التي يستخدمها التطبيق في الجمعية الأساسية ، دعونا نقول App.Core (مثل PersonBase).

ثم لدينا تطبيقات هذه الواجهات في Services.Real (مثل Bob.dll).

في حالتنا نحن أيضا Service.Fake, التي تستخدم في تسهيل اختبار UI مع الاعتماد على غيرها من خدمات المؤسسة وقواعد البيانات ، إلخ.

الواجهة الأمامية "العميل" التطبيق نفسه (في حالتنا ، ASP.NET MVC التطبيق) المراجع App.Core.

عندما يبدأ التطبيق, نستخدم Assembly.Load لتحميل المناسبة "الخدمات" تنفيذ DLL ، استنادا إلى التكوين الإعداد.

كل من هذه DLLs له تنفيذ IServiceRegistry بإرجاع قائمة من الخدمات التي تنفذ:

public enum LifestyleType { Singleton, Transient, PerRequest}

public class ServiceInfo {
    public Type InterfaceType {get;set;}
    public Type ImplementationType {get;set;}
    // this might or might not be useful for your app, 
    // depending on the types of services, etc.
    public LifestyleType Lifestyle {get;set;} 
}

public interface IServiceRegistry {
    IEnumerable<ServiceInfo> GetServices();
}

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

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

شيء واحد مهم حقا إذا كنت تفعل هذا:جعل متأكد أن يكون لديك اختبارات تحقق من أنه يمكنك إنشاء كل من "أعلى مستوى" نوع (في حالتنا ، ASP.NET MVC تحكم) مع كل إمكانات تكوين حاوية اللجنة الأولمبية الدولية.

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

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