我認爲這個問題不會重複Autofac: Resolving dependencies with parameters。請閱讀下面的目的部分。需要幫助,我想將參數傳遞給相關組件
我宣佈一個IContentProvider
和一個名爲WebContentProvider
與url
作爲構造函數的參數執行。
interface IContentProvider
{
string Content { get; }
}
class WebContentProvider {
public WebContentProvider(string url) { ... }
public string Content => GetHtmlFrom(this.url);
}
現在,有兩個消費者類需要WebContentProvder來提供來自不同url的內容。它們全部實現接口IContentUser
。
class FirstContentUser : IContentUser
{
IContentProvider provider;
public FirstContentUser(IContentProvider provider)
{
this.provider = provider;
}
public void Use()
{
Console.WriteLine("[First Content User]");
Console.WriteLine(provider.Content);
}
}
類SecondContentUser
與此類似。
這裏是我的註冊代碼:
public AttempAutofac()
{
var builder = new ContainerBuilder();
builder.RegisterType<WebContentProvider>()
.As<IContentProvider>();
// HERE!!! how can I use `url` metadata given below,
// or some other way to get the url while resolving
builder.RegisterType<FirstContentUser>()
.As<IContentUser>()
.WithMetadata("url", "http://the.1st.url");
builder.RegisterType<SecondContentUser>()
.As<IContentUser>()
.WithMetadata("url", "http://the.2nd.url");
container = builder.Build();
}
後來,我想用scope.Resolve<IEnumerable<IContentUser>>()
讓所有消費者實例。
我希望在不久的將來,只需更改一個註冊行,就可以輕鬆地將新類FasterWebContentProvider
配置爲代替WebContentProvider
。
這是我的目的:
Autofac用於根據接口組成的實施方式。我希望一切都在註冊中決定,而不是在解決階段。這意味着消費者提供資源位置,然後Autofac選擇
IContentProvider
實施從該位置加載內容(資源),並將內容提供給特定的消費者。所有接口和實現都是預定義的,所以我不能修改它們(不能使用「Func隱式關係」方式)。
解析
IContentProvider
的參數是動態的,來自不同的消耗,不僅僅是配置值。所以我不能使用該答案中提到的「lambda表達式註冊」方式。也許Autofac模塊可以解決問題,但我不知道該怎麼做。
我不清楚我的設計是否正確。我會感謝能指出如何改進設計的人。
作爲一個側面說明,如果你是手動調用scope.Resolve在代碼中的某個點你已經掉進了服務定位器反模式的陷阱。 –
[Autofac:解決與參數的依賴關係]的可能重複(http://stackoverflow.com/questions/26327177/autofac-resolving-dependencies-with-parameters) –