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 MyRepo
once only, using .InstancePerLifetimeScope()
.
This will be equivalent to .InstancePerHttpRequest()
when used in a web application (I assume that in this case, rather than calling Resolve()
with no parameter, you're just taking a dependency that is injected.)
Then, instead of resolving IMyRepo
directly when passing the parameter, resolve Owned<IMyRepo>
:
using (var repoWithParam = ComponentContext.Resolve<Owned<IMyRepo>>(
new NamedParameter("connection", ...))){
// Use repoWithParam.Value here
}
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.
精彩评论