2015-06-26 191 views
0

我有以下的配置,我想在autofac註冊:Autofac - 註冊(部分)Open Generic。

UploadStrategy1<T> : IUploadStrategy<Thing1, T> 
UploadStrategy3<T> : IUploadStrategy<Thing3, T> 
...... 

這是在這樣的

public class UploadDownloadHandlerStrategy1<T> : IUploadDownloadHandlerStrategy1<T, Thing1, OtherThing1> 
{ 
    public UploadDownloadHandlerStrategy1(IUpoadStrategey<Thing1, T>, 
             IDownloadStrategy<Thing1, OtherThing1>) 
} 

構造這是那些低於它確實有理想的情況之一這是一團糟。其實我很自豪,我把它解開了。

我沒有工作的唯一部分是IUploadStrategy。到目前爲止,大約有8個實現,但它應該擴大規模,所以散裝是可取的。

我只是不知道這應該是什麼樣子在autofac。

builder.??? 
+1

當你解決'IUploadStrategy '你想'UploadStrategy1 '當你解決'IUploadStrategy '你想'UploadStrategy2 '? (工作示例:https://dotnetfiddle.net/cwvait) –

+1

使用簡單注入器,您可以簡單地調用'container.RegisterOpenGeneric(typeof(IUploadStrategy <,>),typeof(UploadStrategy1 <>));',但我不確定if Autofac支持這種情況。 – Steven

+0

@CyrilDurand這部分讓我在那裏,試圖讓我可以註冊'儘可能多',而不是單獨。我想我會需要一個基類。 – Seth

回答

2

讓我們想象一下,你有這幾種:

public class Thing1 { } 
public class Thing2 { } 
public class Thing3 { } 

public interface IUploadStrategy<T1, T2> { } 

public class UploadStrategy1<T> : IUploadStrategy<Thing1, T> { } 
public class UploadStrategy2<T> : IUploadStrategy<Thing2, T> { } 

當你解決IUploadStrategy<Thing1, String>你想Autofac返回的UploadStrategy1<String>一個實例,當你解決IUploadStrategy<Thing2, String>你想要的UploadStrategy2<String>

實例

你可以這樣註冊這些類型:

builder.RegisterGeneric(typeof(UploadStrategy1<>)).As(typeof(IUploadStrategy<,>)); 
builder.RegisterGeneric(typeof(UploadStrategy2<>)).As(typeof(IUploadStrategy<,>)); 

通過這樣做Autofac將自動考慮對T1的限制。

所以,

var s1 = container.Resolve<IUploadStrategy<Thing1, String>>(); 
Console.WriteLine(s1.GetType()); // will be UploadStrategy1 

var s2 = container.Resolve<IUploadStrategy<Thing2, String>>(); 
Console.WriteLine(s2.GetType()); // will be UploadStrategy2 

會按預期工作。請參閱此dotnetfiddle以獲得實況樣本:https://dotnetfiddle.net/cwvait

如果要自動解析這些類型,可以考慮使用RegisterAssemblyTypes方法。不幸的是,這種方法不會讓你做你想做的事,因爲它不是一個RegisterAssemblyGenericTypes方法。你將不得不掃描自己的裝配。例如:

foreach (Type t in typeof(Program).Assembly 
            .GetLoadableTypes() 
            .Where(t => t.GetInterfaces() 
               .Any(i => i.IsGenericType 
                 && i.GetGenericTypeDefinition() == typeof(IUploadStrategy<,>)))) 
{ 
    builder.RegisterGeneric(t).As(typeof(IUploadStrategy<,>)); 
} 

GetLoadableTypes方法是位於Autofac.Util命名空間擴展方法,這是內部使用RegisterAssemblyTypes方法的方法。