我目前正在使用Unity通过conventions注入我的所有通用存储库,但是我想通过在运行时知道其通用类型来解析其构造函数参数之一,即
public class ReadOnlyRepository<T> : IReadOnlyRepository<T>
where T : class
{
// All subclasses have the same constructor signature
public ReadOnlyRepository(IMongoClient client, MongoDatabaseSettings databaseSettings, string databaseName)
{
this.Context = client.GetDatabase(databaseName, databaseSettings);
}
protected IMongoDatabase Context { get; set; }
}
(通常,您会inject the IMongoDatabase
itself,但我想允许在构造时指定数据库设置)
我用于数据库名称的约定只是实体的名称,例如ReadOnlyRepository<Car>
将在名为“ Car”的数据库上运行。因此,我的注入代码看起来像这样
var connection = ConfigurationManager.ConnectionStrings[MongoConnectionString].ConnectionString;
var repositories = typeof(IReadOnlyRepository<>)
.Assembly
.GetTypes()
.Where(t =>
t.IsClass &&
t.GetInterfaces().Any(i =>
i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IReadOnlyRepository<>)));
var container = new UnityContainer()
.RegisterInstance<IMongoClient>(new MongoClient(connection))
.RegisterTypes(
repositories,
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Transient,
t => new[]
{
new InjectionFactory((container, type) => new <RepoConstructor>(
container.Resolve<IMongoClient>(),
null, // My project doesn't need specific settings
type.GetGenericArguments()[0].Name))
});
出现问题是因为自从我按照约定进行注册以来,我无法直接访问每个构造函数。我也许可以使用反射来访问它,但是据我所知,这个工厂将被称为每种分辨率,而且反射很慢。
我想出的唯一选择是将默认名称移到构造函数中,但是我想知道是否还有另一种方法。