开发者

Autofac component building based on ctor parameters

开发者 https://www.devze.com 2023-03-28 23:04 出处:网络
Is it possible to register components in a way so that they can be resolved based on constructor parameters?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消