I just started moving to Autofac from Unity and I have a problem when trying to register an instance.
public static void Register(ContainerBuilder containerBuilder,
CancellationToken shutDownCancellationToken)
{
containerBuilder.RegisterType<CancellationToken>();
containerBuilder.RegisterInstance(shutDownCancellationToken);
}
I get the following error:
The type '
CancellationToken
' must be a reference type in order to use it as parameter 'T
' in the generic type or method 'RegistrationExtensions.RegisterInstance<T>(ContainerBuilder, T)
'
Anyone knows how to register an already created struct instance?
The RegisterInstance
method as a class
constraint that disallow struct
registration but CancellationToken
is a struct
this is why you have this error message. To bypass this constraint, you can register your instance using the Register
method.
builder.Register(_ => source.Token).As<CancellationToken>();
As long as your struct is immutable, you will have the expected behavior, but if you use a mutable struct, the instance won't be share. In your case, CancellationToken
is immutable you won't have any weird side effect.
But why has RegisterInstance
a class
constraint ?
When you register an instance using the RegisterInstance
method, the expected behavior is to share the same instance each time the object is injected.
By definition a struct
acts like a copy and not like a reference. See Struct vs Class for more information.
Imagine you have the following struct and service using this 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);
}
}
and the following code using these service :
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();
Even if you register only one instance of Foo
it will display 3 and 0. I think this is the reason why RegisterInstance
has a class
constraint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With