Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在asp.net core 2依赖项注入中,有没有办法注册和加载实现一级接口的类?_C#_Asp.net Core - Fatal编程技术网

C# 在asp.net core 2依赖项注入中,有没有办法注册和加载实现一级接口的类?

C# 在asp.net core 2依赖项注入中,有没有办法注册和加载实现一级接口的类?,c#,asp.net-core,C#,Asp.net Core,我有以下资料: interface IExpirable{ Expire(int id); } interface IExpirableA : IExpirable { MethodA(); } interface IExpirableB : IExpirable { MethodB(); } public class A : IExpirableA {//implement both methods Expire, and MethodA} public class B :

我有以下资料:

interface IExpirable{
   Expire(int id);
}

interface IExpirableA : IExpirable {
  MethodA();
}

interface IExpirableB : IExpirable {
  MethodB();
}

public class A : IExpirableA {//implement both methods Expire, and MethodA}
public class B : IExpirableB {//implement both methods Expire, and MethodB}

//in Startup.cs

services.AddScoped<IExpirableA , A>();
services.AddScoped<IExpirableB , B>();

//in HomeController.cs

private readonly IEnumerable<IExpirable> _expirables;
public HomeController(IEnumerable<IExpirable> expirables){
  expirables = _expirables;

    //here expirables is an empty array, however I would like it to contain instances of both A and B because
    // A -> IExpirableA -> Expirable and likewise for B.
    //is this something that can be accomplished without separately 
   //registering A and B with IExpirable each?
    }
接口可扩展{
过期(int-id);
}
接口IExpirableA:IExpirable{
方法a();
}
接口IExpirableB:IExpirable{
方法b();
}
公共类A:IExpirableA{//实现这两个方法过期,而MethodA}
公共类B:IExpirableB{//实现两个方法都过期,而MethodB}
//在Startup.cs中
services.addScope();
services.addScope();
//在HomeController.cs中
私有只读IEnumerable\u可过期文件;
公共家庭控制器(IEnumerable expirables){
到期资产=_到期资产;
//这里expirables是一个空数组,但是我希望它同时包含A和B的实例,因为
//A->IExpirableA->可到期,同样适用于B。
//这是不需要单独完成的事情吗
//分别向IExpirable注册A和B?
}

您可以使用工厂方法针对多个接口注入同一实例

services.addScope();
services.addScope();
services.addScope(p=>p.GetService());
services.addScope(p=>p.GetService());

您可以编写一个扩展方法,使用反射来发现和注册所有实现的接口。

您可以使用工厂方法对多个接口注入相同的实例

services.addScope();
services.addScope();
services.addScope(p=>p.GetService());
services.addScope(p=>p.GetService());

您可以编写一个扩展方法,使用反射来发现和注册所有实现的接口。

只需使用超级接口注册这些服务IExpirable就可以了

services.addScope();
services.addScope();

但是,要小心这个构造函数

公共家庭控制器(
i可数到期资产,
I expirableA到期A,
IExpirableB到期b)
{ 
}
如果你不想得到这样的异常

InvalidOperationException: Unable to resolve service for type 'IExpirableA' while attempting to activate 'HomeController'.
你也许可以通过这种方式来提高

services.addScope();
services.addScope();
services.AddDerivedExpirables(ServiceLifetime.Scoped);
使用IServiceCollection扩展名

公共静态类ServiceCollectionExtension
{
公共静态IServiceCollection AddDerivedExpirables(此IServiceCollection服务,服务生命周期)
{
var scansassemblies=AppDomain.CurrentDomain.GetAssemblies().ToList();
var interfaceTypes=scansassemblies.SelectMany(o=>o.DefinedTypes)
.其中(x=>x.i界面)
.Where(x=>x!=typeof(IExpirable))//排除超级接口
.Where(x=>typeof(IExpirable).IsAssignableFrom(x))
);
foreach(interfaceType中的变量interfaceType)
{
变量类型=扫描程序集。选择多个(o=>o.DefinedTypes
.其中(x=>x.IsClass)
.Where(x=>interfaceType.IsAssignableFrom(x))
);
foreach(类型中的变量类型)
{
TryAdd(新的ServiceDescriptor(接口类型、类型、生存期));
}
}
返回服务;
}
}
此扩展自动注册所有其他接口,如从超级接口导出的
IExpirableA
IExpirableB
等。试着切换到你的需要


中有一个示例演示了AddOptions()的工作原理。可能会有帮助。

只需使用其超级接口注册这些服务IExpirable即可

services.addScope();
services.addScope();

但是,要小心这个构造函数

公共家庭控制器(
i可数到期资产,
I expirableA到期A,
IExpirableB到期b)
{ 
}
如果你不想得到这样的异常

InvalidOperationException: Unable to resolve service for type 'IExpirableA' while attempting to activate 'HomeController'.
你也许可以通过这种方式来提高

services.addScope();
services.addScope();
services.AddDerivedExpirables(ServiceLifetime.Scoped);
使用IServiceCollection扩展名

公共静态类ServiceCollectionExtension
{
公共静态IServiceCollection AddDerivedExpirables(此IServiceCollection服务,服务生命周期)
{
var scansassemblies=AppDomain.CurrentDomain.GetAssemblies().ToList();
var interfaceTypes=scansassemblies.SelectMany(o=>o.DefinedTypes)
.其中(x=>x.i界面)
.Where(x=>x!=typeof(IExpirable))//排除超级接口
.Where(x=>typeof(IExpirable).IsAssignableFrom(x))
);
foreach(interfaceType中的变量interfaceType)
{
变量类型=扫描程序集。选择多个(o=>o.DefinedTypes
.其中(x=>x.IsClass)
.Where(x=>interfaceType.IsAssignableFrom(x))
);
foreach(类型中的变量类型)
{
TryAdd(新的ServiceDescriptor(接口类型、类型、生存期));
}
}
返回服务;
}
}
此扩展自动注册所有其他接口,如从超级接口导出的
IExpirableA
IExpirableB
等。试着切换到你的需要

中有一个示例演示了AddOptions()的工作原理。也许会有帮助