将 class 实例注入通用接口
Injecting a class instance to a generic interface
我有这个型号class:
public class FunctieModel: ObservableObject
{ ... }
存储库的基本接口:
public interface IBaseRepo<T> where T : ObservableObject
{
void Delete(int id);
T GetItem(int id);
IEnumerable<T> GetList();
bool Update(T model);
bool Insert(T model);
}
FunctieModel 类型存储库的特定接口
public interface IFunctieRepo : IBaseRepo<FunctieModel>
{}
我的 FunctieModels 存储库的实现:
public class FunctieRepoSql : IFunctieRepo
{...}
我的测试人员 class 必须能够使用必须注入的存储库:
public class Tester
{
IBaseRepo<ObservableObject> repo;
public Tester(IBaseRepo<ObservableObject> repo)
{
this.repo = repo;
}
}
这一切编译正常。现在我需要用不同的存储库实例化测试器 class。
new Tester(new FunctieRepoSql())
这就是我的问题所在。错误是
无法从 FunctieRepoSql
转换为 IBaseRepo<ObservableObject>
我显然遗漏了一些东西。任何人都知道我如何让它工作?
您无法将 IBaseRepo<FunctieModel>
转换为 IBaseRepo<ObservableObject>
。例如,假设有一个通用集合,假设是猫,如果将其转换为动物集合,则可以向其中添加一只狗,这是不可取的。但是,您可以在此处使用 out
关键字:
public interface IBaseRepo<out T> where T : ObservableObject
但是你将无法接受 ObservableObjects 作为输入 (msdn about out)。
您有两个关键选项需要考虑。最简单的方法是简单地使 Tester
通用并使用一个可以传递给 IBaseRepo<T>
的类型参数。
public class Tester<T> where T : ObservableObject
{
IBaseRepo<T> repo;
public Tester(IBaseRepo<T> repo)
{
this.repo = repo;
}
}
那么您可以将调用代码更改为:
new Tester<FunctieModel>(new FunctieRepoSql())
如果出于某种原因您不能使用此技术,您可以改为创建另一个非通用接口,IBaseRepo
IBaseRepo<T>
扩展。它应该将等效方法表面化为 IBaseRepo<T>
(对于那些使用 T
的方法),而是在不使用该类型参数的情况下声明它们。这类似于 IEnumerable
和 IEnumerable<T>
。完成此操作后,您可以让 Tester
在其构造函数中接受 IBaseRepo
而不是通用版本。
我有这个型号class:
public class FunctieModel: ObservableObject
{ ... }
存储库的基本接口:
public interface IBaseRepo<T> where T : ObservableObject
{
void Delete(int id);
T GetItem(int id);
IEnumerable<T> GetList();
bool Update(T model);
bool Insert(T model);
}
FunctieModel 类型存储库的特定接口
public interface IFunctieRepo : IBaseRepo<FunctieModel>
{}
我的 FunctieModels 存储库的实现:
public class FunctieRepoSql : IFunctieRepo
{...}
我的测试人员 class 必须能够使用必须注入的存储库:
public class Tester
{
IBaseRepo<ObservableObject> repo;
public Tester(IBaseRepo<ObservableObject> repo)
{
this.repo = repo;
}
}
这一切编译正常。现在我需要用不同的存储库实例化测试器 class。
new Tester(new FunctieRepoSql())
这就是我的问题所在。错误是
无法从 FunctieRepoSql
转换为 IBaseRepo<ObservableObject>
我显然遗漏了一些东西。任何人都知道我如何让它工作?
您无法将 IBaseRepo<FunctieModel>
转换为 IBaseRepo<ObservableObject>
。例如,假设有一个通用集合,假设是猫,如果将其转换为动物集合,则可以向其中添加一只狗,这是不可取的。但是,您可以在此处使用 out
关键字:
public interface IBaseRepo<out T> where T : ObservableObject
但是你将无法接受 ObservableObjects 作为输入 (msdn about out)。
您有两个关键选项需要考虑。最简单的方法是简单地使 Tester
通用并使用一个可以传递给 IBaseRepo<T>
的类型参数。
public class Tester<T> where T : ObservableObject
{
IBaseRepo<T> repo;
public Tester(IBaseRepo<T> repo)
{
this.repo = repo;
}
}
那么您可以将调用代码更改为:
new Tester<FunctieModel>(new FunctieRepoSql())
如果出于某种原因您不能使用此技术,您可以改为创建另一个非通用接口,IBaseRepo
IBaseRepo<T>
扩展。它应该将等效方法表面化为 IBaseRepo<T>
(对于那些使用 T
的方法),而是在不使用该类型参数的情况下声明它们。这类似于 IEnumerable
和 IEnumerable<T>
。完成此操作后,您可以让 Tester
在其构造函数中接受 IBaseRepo
而不是通用版本。