我正在尝试使用工厂解决策略模式。该工厂生成一个开放的通用接口。它取决于该通用接口的IEnumerable。我可以获得非泛型的IEnumerable,但是使用泛型时,我得到一个空列表。
我也可以直接解析类,但不能直接解析列表。
另一个警告是,我们可能拥有无限的存储库,因此单独注册它们会很痛苦。
我尝试了这些方法来向Autofac注册
var dataAccess = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(dataAccess).AsClosedTypesOf(typeof(Repositories.IRepository<>));
builder.RegisterAssemblyTypes(dataAccess)
.Where(t => IsAssignableToGenericType(t, typeof(Repositories.IRepository<>)) && !t.IsAbstract && !t.IsInterface)
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(dataAccess)
.Where(t => IsAssignableToGenericType(t, typeof(Repositories.IRepository<>)) && !t.IsAbstract && !t.IsInterface);
public interface IRepository<T> where T : BaseProcessorType
{
Task Add(T data);
}
public abstract class BaseRepository<T> : IRepository<T> where T : BaseProcessorType
{
public async Task Add(T data)
{
// something
}
}
public class ActivityRepository : BaseRepository<Activity>, IRepository<Activity>
{
public ActivityRepository() : base()
{
}
public override async Task Add(Activity data)
{
// override
}
}
那我想解决
var lol = something.Resolve<IEnumerable<Repositories.IRepository<BaseProcessorType>>>();
但是不幸的是,这会返回一个空的IRepositories列表。
答案 0 :(得分:3)
让我们忘记Autofac
,让我们尝试使用纯C#来获取集合。
IEnumerable<IRepository<BaseProcessorType>> l = new IRepository<BaseProcessorType>[] {
new ActivityRepository()
};
使用代码示例,编译器将引发错误
错误CS0266 -无法将类型
ActivityRepository
隐式转换为IRepository<BaseProcessorType>
。存在显式转换(您是否缺少演员表?)
主要错误是ActivityRepository
无法转换为IRepository<BaseProcessorType>
。为了允许这种类型的转换,您必须使用T
关键字使out
参数协变
public interface IRepository<out T> where T : BaseProcessorType
{}
但是这样做,您将无法获得带有T
参数的方法
错误CS1961 :无效的变化:类型参数
T
在IRepository<T>.Add(T)
上必须是反有效的。T
是协变的。
要了解为什么禁止使用该代码,请看以下代码示例:
IRepository<BaseProcessorType> r = new Activity1Repository();
r.Add(new Activity2());
在此代码示例中,r
与Activity1
一起使用,但是您要添加Activity2
,而Activity1
不是Activity2
。
一种解决方案是不使用T
作为类型参数,而使用BaseProcessorType
public interface IRepository<out T> where T : BaseProcessorType
{
Task Add(BaseProcessorType data);
}
这样,纯C#解决方案才有效。
为了解析IEnumerable<IRepository<BaseProcessorType>>
,您需要将类型注册为IRepository<BaseProcessorType>
。
builder.RegisterAssemblyTypes(dataAccess)
.As(typeof(IRepository<BaseProcessorType>));