我刚开始从 Unity 转移到 Autofac ,我在尝试注册实例时遇到了问题。
public static void Register(ContainerBuilder containerBuilder,
CancellationToken shutDownCancellationToken)
{
containerBuilder.RegisterType<CancellationToken>();
containerBuilder.RegisterInstance(shutDownCancellationToken);
}
我收到以下错误:
“
中将其用作参数“CancellationToken
”类型必须是引用类型才能在通用类型或方法“T
”RegistrationExtensions.RegisterInstance<T>(ContainerBuilder, T)
”
任何人都知道如何注册已经创建的结构实例?
答案 0 :(得分:9)
作为RegisterInstance
约束的class
方法禁止struct
注册但CancellationToken
为struct
这就是您收到此错误消息的原因。要绕过此约束,您可以使用Register
方法注册实例。
builder.Register(_ => source.Token).As<CancellationToken>();
只要您的结构是不可变的,您将具有预期的行为,但如果您使用可变结构,则实例将不会共享。在您的情况下,CancellationToken
是不可变的,您不会有任何奇怪的副作用。
但为什么RegisterInstance
有class
约束?
使用RegisterInstance
方法注册实例时,预期的行为是每次注入对象时共享同一实例。
根据定义,struct
的行为类似于副本,而不像引用。有关详细信息,请参阅Struct vs Class。
想象一下,使用这个结构你有以下结构和服务:
public struct Foo
{
public Int32 A { get; set; }
}
public class Service
{
public Service(Foo foo)
{
this._foo = foo;
}
private Foo _foo;
public void Set(Int32 a)
{
this._foo.A = a;
}
public void Print()
{
Console.WriteLine(this._foo.A);
}
}
以及使用这些服务的以下代码:
var builder = new ContainerBuilder();
Foo f = new Foo();
builder.Register(_ => f).As<Foo>();
builder.RegisterType<Service>();
IContainer container = builder.Build();
Service service1 = container.Resolve<Service>();
Service service2 = container.Resolve<Service>();
service1.Set(3);
service1.Print();
service2.Print();
即使您只注册一个 Foo
实例,它也会显示3和0.我认为这就是RegisterInstance
有class
约束的原因。