[英]C#, Autofac: NamedParameter is not provided in Register<>
我目前正在嘗試一些 autofac 功能,並且正在努力使用 NamedParameter。
我創建了一個非常簡單的示例,其中IFoo
由HappyFoo
和SadFoo
實現。 IFooUser
在構造函數中需要一個IFoo
對象,並使用它向控制台打印一些東西。
下面的代碼顯示了我如何嘗試構建一個IFooUser
對象,該對象將使用基於“分數”值的IFoo
對象。
var builder = new ContainerBuilder();
builder.RegisterType<NormalFooUser>().As<IFooUser>();
builder.Register<IFoo>((context, parameters) =>
{
var score = parameters.Named<int>("score"); // ! Exception !
if (score >= 100)
{
return new HappyFoo();
}
return new SadFoo();
});
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
scope.Resolve<IFooUser>(new NamedParameter("score", 90)).useFoo();
}
不幸的是,當我執行此代碼時, parameters
序列不包含任何值 => 異常! 當我決定使用IFoo
一切正常:
scope.Resolve<IFoo>(new NamedParameter("score", 90)).foo(); // Works
但這不是我想做的。 所以我想知道怎樣才能構建一個IFooUser
與IFoo
對應與NamedParameter“分數”的對象。
謝謝。
NamedParameter
旨在配置請求的組件而不是整個依賴圖,該參數不會在整個注冊過程中傳播,它不是上下文參數。
如果你想要一個上下文,你可以實現這樣一個組件來存儲一些屬性。
// interface
interface IContext {
T Get<T>(String name);
void Set<T>(String name, T value);
}
// registration
builder.RegisterType<FooContext>().As<IContext>();
builder.Register<IFoo>(c =>
{
var score = c.Resolve<IContext>().Get<Int32>("score");
if (score >= 100)
{
return new HappyFoo();
}
return new SadFoo();
});
// usage
using (ILifetimeScope scope = container.BeginLifetimeScope())
{
scope.Resolve<IContext>().Set("score", 90);
scope.Resolve<IFooUser>().useFoo();
}
這種方法的優點是您可以在當前生命周期范圍內隨時設置上下文屬性。 您還可以想象沒有Set
方法的實現,它將根據您想要的任何內容檢索值。
另一種做同樣事情的方法是使用Func<Int32, IFoo>
依賴項和TypedAs
方法
builder.Register<IFoo>((c, p) =>
{
Int32 score = p.TypedAs<Int32>();
if (score >= 100)
{
return new HappyFoo();
}
return new SadFoo();
});
當然你必須改變IFooUser
接口和實現
public class NormalFooUser : IFooUser
{
private readonly Func<Int32, IFoo> _fooBuilder;
public NormalFooUser(Func<Int32,IFoo> fooBuilder)
{
_fooBuilder = fooBuilder;
}
public void useFoo(Int32 score)
{
_fooBuilder(score).foo();
}
}
scope.Resolve<IFooUser>(new NamedParameter("score", 90))
告訴 Autofac 它應該使用參數score
來創建注冊為IFooUser
的實例,但實際上它不需要它 - 它的依賴項IFoo
需要它。 Autofac 不會自動將這些參數傳遞給類型的依賴項,您需要自己完成,只需在IFooUser
注冊時傳遞參數
builder.Register((c, p) => new NormalFooUser(c.Resolve<IFoo>(p))).As<IFooUser>();
此代碼段傳遞用於解析IFooUser
所有參數,您只能將其限制為這些必需的
builder.Register((c, p) => new NormalFooUser(c.Resolve<IFoo>(new NamedParameter("score", p.Named<int>("score"))))).As<IFooUser>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.