首页 > 解决方案 > 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>>();
    }
}

标签: autofac

解决方案


据我了解,您可以尝试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);.


推荐阅读