Can't register struct instance with autofac
I just started migrating to Autofac from Unity and I got a problem trying to register an instance.
public static void Register(ContainerBuilder containerBuilder,
CancellationToken shutDownCancellationToken)
{
containerBuilder.RegisterType<CancellationToken>();
containerBuilder.RegisterInstance(shutDownCancellationToken);
}
I am getting the following error:
Type '
CancellationToken
' must be a reference type in order to use it as a parameter 'T
' in a generic type or method 'RegistrationExtensions.RegisterInstance<T>(ContainerBuilder, T)
'
Does anyone know how to register an already created instance of a struct?
source to share
Method RegisterInstance
as restriction class
prohibiting registration struct
, and CancellationToken
- struct
, so you have this error message. To work around this limitation, you can register your instance using the Register
.
builder.Register(_ => source.Token).As<CancellationToken>();
As long as your structure is immutable, you will have the expected behavior, but if you use a mutable structure, the instance will not be used. In your case CancellationToken
unchanged, you won't have any strange side effect.
But why the constraint RegisterInstance
a class
?
When you register an instance using a method RegisterInstance
, the expected behavior is to share the same instance every time the object is injected.
By definition, a struct
acts like a copy and not like a link. See Struct vs Class for more information .
Imagine you have the following structure and service using this structure:
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 this 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 only register one instance Foo
it will display 3 and 0. I think this is the reason it RegisterInstance
has a limitation class
.
source to share