在评估Func<T>
T注册InstancePerMatchingLifetimeScope
时,在单例类中,它不应该提供相同的实例吗?也就是说,Func<T>
不应该是“范围感知”?
也许一个例子会更好。
我有两节课:
class MyScoped
{
public int Num { get; set; }
}
class MySingleton
{
readonly Func<MyScoped> scoped;
public MySingleton(Func<MyScoped> scoped)
{
this.scoped = scoped;
}
public void Do()
{
var scopedObj = scoped();
Console.WriteLine(scopedObj.Num);
}
}
注册如下:
var builder = new ContainerBuilder();
builder.RegisterType<MyScoped>().InstancePerMatchingLifetimeScope("MyScope", "root");
builder.RegisterType<MySingleton>().SingleInstance();
var container = builder.Build();
我正在运行以下代码:
var singleton = container.Resolve<MySingleton>();
singleton.Do();
using (var scope = container.BeginLifetimeScope("MyScope"))
{
var scoped = scope.Resolve<MyScoped>();
scoped.Num = 1;
singleton.Do();
}
我希望第一次拨打Do()
会打印0,第二次拨打会打印1。
我必须将MySingleton
更改为InstancePerDependency
以便它可以正常工作,这对我来说是一个糟糕的解决方案,因为创建MySingleton
代价很高。
我在这里缺少什么?
答案 0 :(得分:0)
似乎在根范围的上下文中解析了注册为单个实例的服务。这意味着注入Func<MyScoped>
的{{1}}将始终从根目录解析MySingleton
。以下代码:
MyScoped
将打印两次,因为var singleton = container.Resolve<MySingleton>();
var s = container.Resolve<MyScoped>();
s.Num = 1;
singleton.Do();
using (var scope = container.BeginLifetimeScope("MyScope"))
{
var scoped = scope.Resolve<MyScoped>();
scoped.Num = 10;
singleton.Do();
}
方法中的var scopedObj = scoped();
将从根容器解析Do()
,而不是从范围解析。
您可以通过手动将所需的依赖项传递到MyScoped
方法来实现您的目标:
Do()
它将分别打印class MySingleton
{
public void Do(MyScoped myScoped)
{
Console.WriteLine(myScoped.Num);
}
}
// ...
var singleton = container.Resolve<MySingleton>();
var s = container.Resolve<MyScoped>();
s.Num = 1;
singleton.Do(s);
using (var scope = container.BeginLifetimeScope("MyScope"))
{
var scoped = scope.Resolve<MyScoped>();
scoped.Num = 10;
singleton.Do(scoped);
}
和1
。