Is it possible to register components in a way so that they can be resolved based on constructor parameters?
public interface IRepository<T>{}
public interface IMyRepo {}
public class MyRepo : IRepository<TEntity>, IMyRepo
{
public MyRepo(IDbConnection connection){}
public MyRepo(){}
}
// lots of other repositories...
public class Global
{
public void BuildDIContainer()
{
var builder = new ContainerBuilder();
var assembly = Assembly.GetExecutingAssembly();
//any class that implements IRepository<T> is instance per request
builder.RegisterAssemblyTypes(typeof (IRepository<>).Assembly, assembly)
.AsClosedTypesOf(typeof (IRepository<>))
.AsImplementedInterfaces().InstancePerHttpRequest();
//any class that implements IRepository<T> with IDbConnection as ctor parameter is instance per dependency
builder.RegisterAssemblyTypes(typeof(IRepository<>).Assembly, assembly)
.UsingConstructor(typeof(IDbConnection)) // <-- ??
.AsClosedTypesOf(typeof(IRepository<>))
.AsImplementedInterfaces().InstancePerDependency();
//............
//per dependency
var repo1 = ComponentContext.Resolve<IMyRepo>(new NamedParameter("connection", new SqlConnection("...")));
//per request
var repo2 = ComponentContext.Resolve<IMyRepo>();
}
}
Register
MyRepoonce only, using.InstancePerLifetimeScope().This will be equivalent to
.InstancePerHttpRequest()when used in a web application (I assume that in this case, rather than callingResolve()with no parameter, you’re just taking a dependency that is injected.)Then, instead of resolving
IMyRepodirectly when passing the parameter, resolveOwned<IMyRepo>:This will have the added advantage of ensuring that your repository resolved with the custom connection is properly released.
Hope this helps, making a few assumptions about your scenario so let me know if anything is unclear.