从模型到存储库的Autofac参数解析

时间:2018-09-15 23:18:08

标签: autofac

在Autofac容器注册期间如何在Model:DatabaseName中将参数设置到MyRepository构造函数中?

这是代码示例:

public class ModelBase
{
    public string DatabaseName;
}

public interface IRepository<TEntity>
    where TEntity : ModelBase
{

}

public class MyRepository<TEntity> : IRepository<TEntity>
    where TEntity : ModelBase
{
    private readonly string _connectionString;
    public MyRepository(string databaseName)
    {
        _connectionString = string.Format("DatabaseName='{0}';...", databaseName);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var containerBuilder = new ContainerBuilder();
        containerBuilder.RegisterGeneric(typeof(MyRepository<>)).As(typeof(IRepository<>));

        IContainer container = containerBuilder.Build();
        var someRepository = container.Resolve<IRepository<ModelBase>>();
    }
}

1 个答案:

答案 0 :(得分:1)

据我了解,您可以尝试使用某种代码从存储库的通用参数中提取DatabaseName的值:

public class ModelBase
{
    public virtual string DatabaseName { get; } = "MyDataBase";
}

public class SubModelBase : ModelBase
{
    public override string DatabaseName { get; } = "AnotherDataBase";
}

public interface IRepository<TEntity>
    where TEntity : ModelBase
{

}

public class MyRepository<TEntity> : IRepository<TEntity>
    where TEntity : ModelBase
{
    private readonly string _connectionString;
    public MyRepository(string databaseName)
    {
        _connectionString = string.Format("DatabaseName='{0}';...", databaseName);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var containerBuilder = new ContainerBuilder();
        containerBuilder.RegisterGeneric(typeof(MyRepository<>)).As(typeof(IRepository<>)).WithParameter((p, ctx) => true, (p, ctx) =>
        {
            var repType = p.Member.DeclaringType;
            var genericParamType = repType.GenericTypeArguments[0];
            var prop = genericParamType.GetProperty("DatabaseName");
            var databaseName = prop.GetValue(Activator.CreateInstance(genericParamType));
            // or for static DatabaseName
            // var databaseName = prop.GetValue(null);
            return databaseName;
        });

        IContainer container = containerBuilder.Build();
        var someRepository = container.Resolve<IRepository<ModelBase>>();
        var anotherRepository = container.Resolve<IRepository<SubModelBase>>();
    }
}

请注意,必须为默认的DatabaseName实例确定ModelBase,并且类型必须具有无参数构造函数。或者,您可以将DatabaseName设为静态,并在编译时为其赋值。在这种情况下,您可以致电var databaseName = prop.GetValue(null);