I'm registering some concrete types using the Autofac Keyed options. This all appeared to be working fine until I added a generic parameter to the types and interface.
My registration looks like this:
builder.RegisterType<Customer.DataAccess.Database.StoreElasticConnectionManagerByCompany>();
builder.RegisterType<Customer.DataAccess.Database.StoreElasticConnectionManagerByStore>();
builder.RegisterType<Customer.DataAccess.Database.StoreElasticConnectionManager>();
builder.RegisterType<Customer.DataAccess.Database.DatabaseManagement>().As<IDatabaseManagement>();
builder.RegisterType<ConnectionManagerFactory<Customer.DataAccess.Database.StoreElasticConnectionManagerByStore>>()
.Keyed<IConnectionManagerFactory<IConnectionManager>>(DatabaseConnectionShardingTypes.StoreDatabaseByStoreId);
builder.RegisterType<ConnectionManagerFactory<Customer.DataAccess.Database.StoreElasticConnectionManagerByCompany>>()
.Keyed<IConnectionManagerFactory<IConnectionManager>>(DatabaseConnectionShardingTypes.StoreDatabaseByCompanyId);
builder.RegisterType<DatabaseManagement>().As<IDatabaseManagement>().SingleInstance();
The concrete types and interfaces are implemented like so:
/*The factories*/
public interface IConnectionManagerFactory<T>
where T : IConnectionManager
{}
public class ConnectionManagerFactory<T> : IConnectionManagerFactory<T>
where T : IConnectionManager
{}
/*The Connection Manager*/
public interface IConnectionManager
{}
public abstract class StoreElasticConnectionManager : IConnectionManager
{}
public class StoreElasticConnectionManagerByStore : StoreElasticConnectionManager
{}
When I'm trying to run my code (when the registration is executing) I'm receiving the following error:
An unhandled exception of type 'System.ArgumentException' occurred in Autofac.dll
Additional information: The type 'Customer.DataAccess.Database.ConnectionManagerFactory
1[Customer.DataAccess.Database.StoreElasticConnectionManagerByStore]' is not assignable to service 'StoreDatabaseByStoreId (Customer.DataAccess.Database.IConnectionManagerFactory1[[Customer.DataAccess.Database.IConnectionManager, Customer.DataAccess.Database, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]])'.
This is probably due to the fact I've added the generic parameter to the ConnectionManagerFactory, because it worked before I did this.
I've tried adding the following:
builder.RegisterGeneric(typeof(Customer.DataAccess.Database.ConnectionManagerFactory<>))
.As(typeof(IConnectionManagerFactory<>));
But this didn't appear to solve the issue.
Any advice on how to proceed?
edit
In response to nemesv's question, this is the code which works and where I'm not using generics
builder.RegisterType<Customer.DataAccess.Database.StoreElasticConnectionManagerByCompany>();
builder.RegisterType<Customer.DataAccess.Database.StoreElasticConnectionManagerByStore>();
builder.RegisterType<Customer.DataAccess.Database.StoreElasticConnectionManager>();
builder.RegisterType<ConnectionManagerFactory<Customer.DataAccess.Database.StoreElasticConnectionManagerByStore>>()
.Keyed<IConnectionManagerFactory>(DatabaseConnectionShardingTypes.StoreDatabaseByStoreId);
builder.RegisterType<ConnectionManagerFactory<Customer.DataAccess.Database.StoreElasticConnectionManagerByCompany>>()
.Keyed<IConnectionManagerFactory>(DatabaseConnectionShardingTypes.StoreDatabaseByCompanyId);
As you can see, the interface IConnectionManagerFactory isn't generic anymore.
The concrete ConnectionManagerFactory now looks like this:
public class ConnectionManagerFactory<T> : IConnectionManagerFactory
where T : IConnectionManager
The DatabaseConnectionShardingTypes is a simple enum.
I've solved my issue now by changing the code a bit and not using generics anymore, but I'd still like to know what I'm doing wrong in the above example.