Registering class by multiple abstractions while creating the type by hand

0

I want to register class Foo and its interface IBar.

var b = new DbContextOptionsBuilder();
b.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=Connect.Device;Trusted_Connection = True; MultipleActiveResultSets = true;");
_container.Register(() => new DeviceContext(b.Options), Lifestyle.Scoped);
_container.Register<IFoo, DeviceContext>(Lifestyle.Scoped);
_container.Register<IDeviceTypeService, DeviceTypeService>(Lifestyle.Scoped);

This does not work. This is the exception which is thrown on call to Verify:

System.InvalidOperationException HResult=0x80131509 Message=The configuration is invalid. Creating the instance for type IFoo failed. The constructor of type DeviceContext contains the parameter with name 'options' and type DbContextOptions that is not registered. Please ensure DbContextOptions is registered, or change the constructor of DeviceContext. Source=SimpleInjector StackTrace: at SimpleInjector.InstanceProducer.VerifyExpressionBuilding() at SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt(InstanceProducer[] producersToVerify) at SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt() at SimpleInjector.Container.VerifyInternal(Boolean suppressLifestyleMismatchVerification) at SimpleInjector.Container.Verify(VerificationOption option) at Connect.Device.Service.Startup.InitializeContainer(IApplicationBuilder app) in Startup.cs:line 85 at Connect.Device.Service.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in Startup.cs:line 50

Inner Exception 1: ActivationException: The constructor of type DeviceContext contains the parameter with name 'options' and type DbContextOptions that is not registered. Please ensure DbContextOptions is registered, or change the constructor of DeviceContext.

c#
simple-injector
asked on Stack Overflow Oct 12, 2018 by Pavel Voronin • edited Oct 12, 2018 by Steven

1 Answer

1

A registration using Register<TService, TImplementation> (such as your Register<IFoo, DeviceContext>) always uses auto-wiring by analyzing the type's constructor. It will not reuse a previous registration that uses a delegate.

You wish to overwrite auto-wiring and hand-wire DeviceContext, while being able to resolve it by multiple of its types. The way to achieve this is as follows:

var reg = Lifestyle.Scoped.CreateRegistration(
    () => new DeviceContext(b.Options), container);
container.AddRegistration<DeviceContext>(reg);
container.AddRegistration<IFoo>(reg);

Here you create a Registration instance for DeviceContext, which allows you to hand-wire the type, while specifying its lifestyle. This, however, does not register it, which can be done by calling AddRegistration while specifying the type for which it can be resolved.

answered on Stack Overflow Oct 12, 2018 by Steven • edited Jan 23, 2021 by Steven

User contributions licensed under CC BY-SA 3.0