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?

+3


source to share


1 answer


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

.

+7


source







All Articles