gpt4 book ai didi

c# - 参数化实例化如何与单实例生命范围一起工作

转载 作者:行者123 更新时间:2023-11-30 20:43:57 25 4
gpt4 key购买 nike

根据Parameterized Instantiation ( Func<X, Y, B> )文档:

However, if you register an object as SingleInstance() and call the Func<X, Y, B> to resolve the object more than once, you will get the same object instance every time regardless of the different parameters you pass in. Just passing different parameters will not break the respect for the lifetime scope.

具有不同参数构造函数的单例类如何工作?

最佳答案

Autofac 工厂注册不会根据参数缓存实例。

让我们试试下面的类型:

public class Foo
{
public Foo(Int32 a)
{
this._a = a;
}

private readonly Int32 _a;

public override String ToString()
{
return String.Format("a={0}", this._a);
}
}

如果你这样注册:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Foo>().AsSelf().SingleInstance();

Autofac 将始终注册一个实例,无论您如何解析它(即使您使用 Func 工厂):

Func<Int32, Foo> foo1Factory = scope.Resolve<Func<Int32, Foo>>();
Foo foo1 = foo1Factory(1);
Func<Int32, Foo> foo2Factory = scope.Resolve<Func<Int32, Foo>>();
Foo foo2 = foo2Factory(2);

foo1foo2将是相同的实例。

如果您希望每个参数只有一个实例,这意味着您需要多个 Foo 的实例, 所以你不能注册 Foo使用 SingleInstance()方法。您将必须实现一个自定义工厂,该工厂将进行缓存以使每个参数有一个实例:

public class FooFactory
{
public FooFactory(IComponentContext componentContext)
{
this._componentContext = componentContext;
this._instances = new Dictionary<Int32, Foo>();
this._lock = new Object();
}

private readonly IComponentContext _componentContext;
private readonly Dictionary<Int32, Foo> _instances;
private readonly Object _lock;

public Foo GetInstance(Int32 a)
{
Foo parameterizedFoo;
if (!this._instances.TryGetValue(a, out parameterizedFoo))
{
lock (this._lock)
{
if (!this._instances.TryGetValue(a, out parameterizedFoo))
{
Parameter aParameter = new TypedParameter(typeof(Int32), a);
parameterizedFoo = this._componentContext
.Resolve<Foo>(aParameter);
this._instances[a] = parameterizedFoo;
}
}
}
return parameterizedFoo;
}
}

可以这样注册:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Foo>().AsSelf();
builder.RegisterType<FooFactory>().AsSelf().SingleInstance();

使用下面的代码来使用它:

FooFactory fooFactory = scope.Resolve<FooFactory>();
Foo foo = fooFactory.GetInstance(1);

但是如果你想使用Func<Int32, Foo>而不是 FooFactory.GetInstance , 您可以将方法注册为 Func<Int32, Foo> :

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Foo>().AsSelf();
builder.RegisterType<FooFactory>().AsSelf().SingleInstance();
builder.Register(c => new Func<Int32, Foo>(c.Resolve<FooFactory>().GetInstance))
.As<Func<Int32, Foo>>()
.SingleInstance();

您现在可以使用此代码:

Func<Int32, Foo> foo1Factory = scope.Resolve<Func<Int32, Foo>>();
Foo foo1 = foo1Factory(1);
Func<Int32, Foo> foo2Factory = scope.Resolve<Func<Int32, Foo>>();
Foo foo2 = foo2Factory(2);
Func<Int32, Foo> foo1PrimeFactory = scope.Resolve<Func<Int32, Foo>>();
Foo foo1Prime = foo1PrimeFactory(1);

foo1foo2会有所不同,而 foo1Prime将与 foo1 相同.

关于c# - 参数化实例化如何与单实例生命范围一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30000506/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com