I'm trying to register my repository class which is take two generic parameter to repository interface (one parameter generic).
public class RepositoryBase<T, O> : IDataAccess<T>
public interface IDataAccess<T>
I'm trying to register my repository class which is take two generic parameter to repository interface (one parameter generic).
public class RepositoryBase<T, O> : IDataAccess<T>
public interface IDataAccess<T>
Autofac don't know how to set the second generic parameter of RepositoryBase when you only want to provide one generic argument in the interface. So you need to somehow specify the second argument in order to instantiate the service unless you are happy with object, dynamic or some base class. In order to achieve this you can create a factory like this:
public class BaseRepositoryFactory<T1> : IDataAccessFactory<T1>
{
private readonly IComponentContext context;
public BaseRepositoryFactory(IComponentContext context)
{
this.context = context;
}
public IDataAccess<T1> Create<T2>()
{
return context.Resolve<IRepositoryBase<T1, T2>>();
}
}
public interface IDataAccessFactory<T1>
{
IDataAccess<T1> Create<T>();
}
public interface IRepositoryBase<T1, T2> : IDataAccess<T1>
{
}
public class RepositoryBase<T1, T2> : IDataAccess<T1>, IRepositoryBase<T1, T2>
{
}
And then register the services like:
builder.RegisterGeneric(typeof(BaseRepositoryFactory<>))
.As(typeof(IDataAccessFactory<>));
builder.RegisterGeneric(typeof(RepositoryBase<,>))
.As(typeof(IRepositoryBase<,>));
After that you can resolve the factory and create service;
var factory = c.Resolve<IDataAccessFactory<string>>();
IDataAccess<string> serviceInterface = factory.Create<int>();
var serviceConcrete = (RepositoryBase<string, int>)factory.Create<int>();
So this way you can move the declaration of a second argument to a factory method. The drawback of this is that you need to create such factories for each type. To avoid this you can define additional interface with two generic arugments IDataAccess<T1, T2>
and implement it in concrete class and register it so your factory can look like this and will work for any type:
public class DataAccessFactory<T1> : IDataAccessFactory<T1>
{
private readonly IComponentContext context;
public DataAccessFactory(IComponentContext context)
{
this.context = context;
}
public IDataAccess<T1> Create<T2>()
{
return context.Resolve<IDataAccess<T1, T2>>();
}
}
Try this:
builder.RegisterGeneric(typeof(RepositoryBase<,>))
.As(typeof(IDataAccess<>))
.InstancePerRequest();