2010-11-02 37 views
1

比較。使用與我目前使用/與autofac作爲我的IoC控制器嘗試一個簡單的IoC實現

以前到爲此,我使用定義了兩種方法,類似一個簡單的靜態類

public static TService Resolve<TService>() 
public static void Register<IType, ImpType>() 

其中ImpType必須ITYPE的。

現在到autofac。註冊時,你可能會做這樣的事情

builder.RegisterType<ProductRepository>().As<IProductRepository>(); 

但是如果ProductRepository是 - 不一個IProductRepository你沒有得到一個編譯錯誤? 如果需要,有什麼方法可以更安全地連接東西?

其次,建設我的IOC模塊,當我使用類似

public static class IoCContainer 
{ 
    public static IContainer BaseContainer { get; private set; } 

    public static void Build(ContainerBuilder builder) 
    { 
     BaseContainer = builder.Build();    
    } 
} 

後,我已經叫IoCContainer.Build(..)我不能再註冊任何「到」的BaseContainer。將此與簡單模型進行比較,您可以從任何地方註冊任何內容。也許這是設計?

回答

1

我覺得僅僅是因爲C#編譯器(或CLR類型系統)不處理這種類型的約束.RegisterType<Foo>.As<IFoo>模式不是類型安全的。例如,As方法的以下假想聲明不會編譯:

interface IRegistration<TImplementation> 
{ 
    void As<TContract>() where TImplementation : TContract; 
} 

編譯器錯誤是「‘SomeNamespace.IRegistration.As()’不限定類型參數‘TImplementation’」。

是否有接線東西更安全一些方法如果需要的話?

以下似乎工作(雖然它是由Autofac wiki上best practices部分阻止)。除非Foo實現IFoo它會給一個編譯器錯誤:

 var builder = new ContainerBuilder(); 
    builder.Register<IFoo>(c => new Foo()).SingleInstance(); 

    var container = builder.Build(); 
    var foo = container.Resolve<IFoo>(); 

cIComponentContext。如果Foo構造函數需要構造函數參數,則可以編寫c => new Foo(c.Resolve<IBar>())

後,我已經叫IoCContainer.Build(..)我不能再註冊任何 '到' 的BaseContainer

您可以update the container在Autofac 2.2。

+0

謝謝。即使讀過這個鏈接後,我也不會真正意識到builder.Register(c => new Foo())之間的區別。 and builder.Register (c => new Foo());後者看起來優越,因爲它是安全的,而前者不是。不知道爲什麼前者不打字檢查? – wal 2010-11-04 01:20:10

+0

@wal:我已經添加了一個可能的解釋,即'.As'方法不檢查類型。 – 2010-11-04 09:54:08

+0

我也貼出了相關的問題在這裏:http://stackoverflow.com/questions/4095575/constrain-type-parameter-of-a-method-to-the-interfaces-implemented-by-another-typ – 2010-11-04 10:12:01