2011-08-03 78 views
1

我想知道是否有一個標準的方式在c#(或甚至cli)有效地分離實現邏輯到單獨的類庫/程序集,將動態加載一個基於通用接口對這些庫執行操作的進程。如何正確解耦實現細節到類庫中.net

更確切地說: 假設我正在構建一個接收消息並將這些消息的處理委託給其他人的服務。像這樣的:

while(true){ 
    message = read_message_from_somewhere(); 
    class_from_another_lib.do_somthing_with_Message(message); 
} 

我想要進程從某種配置加載運行庫中的類lib。在lib下,我認爲,會有一些主類或類工廠,實現了其中的一些接口部分看起來是這樣的:

ISomePublicIface{ 
    void do_somthing_with_Message(messageT); 
} 

這一切都有點感覺的Java beenish所有我需要做的就是有一類在程序集中實現某種可注入接口,在應用程序配置中添加一行並免費獲取更多東西。

+0

看看這個問題http://stackoverflow.com/questions/2045904/dependency-inject-di-friendly-library/2047657#2047657 – Yahia

回答

6

查看.NET 4.0中包含的Managed Extensibility Framework (MEF)。 MEF可以動態加載和注入來自外部DLL的組件。

+0

我錯過了一些東西,或者MEF沒有提供任何動態加載程序集的功能嗎? 這是我應該照顧自己的東西嗎? – Dmitry

+1

使用AssemblyCatalog從單個程序集加載類型,或使用DirectoryCatalog從給定目錄中的所有程序集加載。它們在[documentation](http://mef.codeplex.com/wikipage?title=Using%20Catalogs&referringTitle=Guide)中有描述, – lnmx

1

如果您喜歡NIH解決方案......我已經寫了一個稍微詳細的問題,它允許您使用DI容器來存儲消息的處理程序並根據消息發送到相關的處理程序。我用autofac的集裝箱在這裏,但任何事情應該是合適的,只要它能夠解決開放泛型:

// Message marker interface 
interface IMessage {} 

// Message handler interface 
interface IHandles<T> where T: IMessage 
{ 
    void Handle(T message); 
} 

// A message which defines mooing 
class MooMessage : IMessage {} 

// A message which defines woofing 
class WoofMessage : IMessage {} 

// A handler for moo messages 
class MooHandler : IHandles<MooMessage> 
{ 
    public void Handle(MooMessage message) 
    { 
     Console.WriteLine("moo"); 
    } 
} 

// A handler for woof messages 
class WoofHandler : IHandles<WoofMessage> 
{ 
    public void Handle(WoofMessage message) 
    { 
     Console.WriteLine("woof"); 
    } 
} 

class Program 
{ 
    // Generate some test messages 
    static IEnumerable<IMessage> MessageGenerator() 
    { 
     yield return new WoofMessage(); 
     yield return new MooMessage(); 
    } 

    static void Main(string[] args) 
    { 
     // configure container 
     var builder = new ContainerBuilder(); 
     // Register message handlers here through configuration or convention... 
     builder.RegisterType<WoofHandler>().AsImplementedInterfaces(); 
     builder.RegisterType<MooHandler>().AsImplementedInterfaces(); 
     var container = builder.Build(); 

     // handle all messages until done 
     foreach (var message in MessageGenerator()) 
     { 
      // resolve the handler for the message from the container 
      var handler = container 
       .Resolve(typeof(IHandles<>) 
       .MakeGenericType(message.GetType())); 

      // call the handler - you have to do this using reflection unfortunately 
      // due to the nature of open generics. 
      handler 
       .GetType() 
       .GetMethod("Handle") 
       .Invoke(handler, new object[] { message }); 
     } 
    } 
} 

你顯然希望從主要提取關注了一點,但它應該給你要點和解決方案的要點。