C# 在.NET内核中注入通用接口
我想将此接口注入我的控制器:C# 在.NET内核中注入通用接口,c#,asp.net-core,dependency-injection,.net-core,asp.net-core-mvc,C#,Asp.net Core,Dependency Injection,.net Core,Asp.net Core Mvc,我想将此接口注入我的控制器: public interface IDatabaseService<T> where T : class { T GetItem(int id); IEnumerable<T> GetList(); void Edit(T data); void Add(T data); void Remove(T data); } 但是当我尝试在我的Startup.cs中插入对象时: service
public interface IDatabaseService<T>
where T : class
{
T GetItem(int id);
IEnumerable<T> GetList();
void Edit(T data);
void Add(T data);
void Remove(T data);
}
但是当我尝试在我的Startup.cs中插入对象时:
services.AddScoped<IDatabaseService<T>>();
它是否有效?将通用接口注入控制器是一种好的做法吗?如果没有,如何做得更好?您可以通过在Startup.cs
// best practice
services.AddTransient(typeof(IDatabaseService<>),typeof(DatabaseService<>));
//最佳实践
AddTransient(typeof(IDatabaseService),typeof(DatabaseService));
如果要编写硬代码,请访问以了解有关ASP.NET核心中依赖项注入的更多信息
services.AddScoped<IDatabaseService<Project>, ProjectService>();
services.AddAllGenericTypes(typeof(IDatabaseService<>), new[] {typeof(ProjectService).GetTypeInfo().Assembly});
services.addScope();
2.)如果要动态注册所有类型的已实现IDatabaseService
System.Reflection.Assembly.getExecutionGassembly()
.GetTypes()
.Where(item=>item.GetInterfaces()
.Where(i=>i.IsGenericType).Any(i=>i.GetGenericTypeDefinition()==typeof(IDatabaseService))&&&!item.isAssect&&!item.IsInterface)
托利斯先生()
.ForEach(已分配类型=>
{
var serviceType=assignedTypes.GetInterfaces().First(i=>i.GetGenericTypeDefinition()==typeof(IDatabaseService));
services.AddScoped(serviceType,assignedTypes);
});
您可以使用services.AddScoped在作用域请求中仅使用一个实例。因此,与ADD相比,总体上有所改进
services.AddScoped(typeof(IGenericRepository)、typeof(genericpository));
因此,我的接口和类将如下所示
公共接口IGenericRepository,其中T:class
公共类GenericRepository:IGenericRepository其中T:class
请随意使用帮助程序:
通过通用接口
services.AddAllGenericTypes(typeof(IDatabaseService<>), new[] {typeof(ProjectService).GetTypeInfo().Assembly});
services.AddAllGenericTypes(typeof(IDatabaseService),new[]{typeof(ProjectService).GetTypeInfo().Assembly});
扩展自:
您应该能够执行服务。addScope(typeof(IDatabaseService))代码>另一个问题是我的思维是否有意义?我在问题中解释的scenerio中的最佳实践是什么?如果它足以将ProjectService
之类的类注入到我的控制器中?当ProjectService
和IDatabaseService
只是一个薄薄的层包装您的DbContext
时,它的好处是什么?直接使用DbContext
并使用其内存提供程序进行测试场景。我只想在DbSet
上使用项目,那么它在“现实生活”场景中是如何工作的呢?最好处理一个IDatabaseService
和DatabaseService
,如果每个控制器都是这样的话?我认为ProjectController
不需要(例如)引用Tasks
services.AddTransient()代码>这不适用于泛型类型,您必须添加具体类型而不是T。使用泛型参数时,必须在编译时知道它们。第二行是注册它的唯一方法,不知道并定义具体类型(每种类型注册),我只想在DbSet
上使用Projects
,那么它在“现实生活”场景中是如何工作的呢?最好处理一个IDatabaseService
和DatabaseService
,如果每个控制器都是这样的话?我认为ProjectController
不需要(例如)参考任务
谢谢您的评论。我删除了错误的示例。谢谢,但正如您在我的问题中所看到的,我希望有像TaskService:IDatabaseService
和ProjectService:IDatabaseService
这样的类。我没有“DatabaseService”类。你能提供关于第二段更复杂的解释吗?如果你有大量实现IDatabaseService接口的服务,它提供查找和注册所有这些服务。例如,这个用例,我们如何处理?公共类GenericRepository:IGenericRepository其中T:U类在代码下面尝试但运行时错误服务的类。AddScope(typeof(IGenericRepository),typeof(GenericRepository));你可以阅读我的博客获取完整的源代码Scrutor可以这样做吗?
System.Reflection.Assembly.GetExecutingAssembly()
.GetTypes()
.Where(item => item.GetInterfaces()
.Where(i => i.IsGenericType).Any(i => i.GetGenericTypeDefinition() == typeof(IDatabaseService<>)) && !item.IsAbstract && !item.IsInterface)
.ToList()
.ForEach(assignedTypes =>
{
var serviceType = assignedTypes.GetInterfaces().First(i => i.GetGenericTypeDefinition() == typeof(IDatabaseService<>));
services.AddScoped(serviceType, assignedTypes);
});
services.AddAllGenericTypes(typeof(IDatabaseService<>), new[] {typeof(ProjectService).GetTypeInfo().Assembly});