无法使用autofac注册结构实例

我刚开始从Unity迁移到Autofac ,我在尝试注册实例时遇到了问题。

public static void Register(ContainerBuilder containerBuilder, CancellationToken shutDownCancellationToken) { containerBuilder.RegisterType(); containerBuilder.RegisterInstance(shutDownCancellationToken); } 

我收到以下错误:

CancellationToken ”类型必须是引用类型才能在generics类型或方法“ RegistrationExtensions.RegisterInstance(ContainerBuilder, T) ”中将其用作参数“ T

任何人都知道如何注册已经创建的结构实例?

RegisterInstance方法作为禁止struct注册的class约束,但CancellationToken是一个struct这就是为什么你有这个错误消息。 要绕过此约束,可以使用Register方法注册实例。

 builder.Register(_ => source.Token).As(); 

只要您的结构是不可变的,您将具有预期的行为,但如果您使用可变结构,则实例将不是共享。 在你的情况下, CancellationToken是不可变的,你不会有任何奇怪的副作用。


但为什么RegisterInstance是一个class约束?

使用RegisterInstance方法注册实例时,预期的行为是每次注入对象时共享同一实例。

根据定义, struct就像一个副本,而不是一个引用。 有关更多信息,请参阅结构与类 。

想象一下,使用这个结构你有以下结构和服务:

 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(); builder.RegisterType(); IContainer container = builder.Build(); Service service1 = container.Resolve(); Service service2 = container.Resolve(); service1.Set(3); service1.Print(); service2.Print(); 

即使你只注册了一个 Foo实例,它也会显示3和0.我认为这就是为什么RegisterInstance有一个class约束的原因。