如何通过其具体类型而不是其接口类型来获取注册服务?

phi*_*-fx 5 c# dependency-injection asp.net-core-2.0

请假设我有以下类和接口:

public class ConcreteRepository : IRepository<T>, IEntityOwner
{ }

public interface IRepository<T>
{ }

public interface IEntityOwner
{ }

public class SomeModel
{ }
Run Code Online (Sandbox Code Playgroud)

假设我已经在我的 Asp.Net Core 2.0 启动类中注册了以下服务:

services.AddScoped<IRepository<SomeModel>, ConcreteRepository>();
Run Code Online (Sandbox Code Playgroud)

我可以像这样获得 ConcreteRepository 的实例:

var concreteRepositoryInstance = 
         httpContext.RequestServices.GetService(typeof(IRepository<SomeModel>))
              as IRepository<SomeModel>;
Run Code Online (Sandbox Code Playgroud)

如何通过 ConcreteRepository 的类型获取 ConcreteRepository 的实例?

我想象这样的事情:

var concreteRepositoryInstance =  
         httpContext.RequestServices.GetService(typeof(ConcreteRepository))
              as IEntityOwner;
Run Code Online (Sandbox Code Playgroud)

请注意,我不能使用任何泛型来回答我的问题,因为我的用例引用了一个自定义属性,该属性将creteRepository 的类型作为输入参数(并且属性在设计上不能是泛型)。

到目前为止我尝试过的:

(a) 我检查并尝试了所有httpContext.RequestServices.GetService...方法,但它们都需要注册具体类型的接口类型。

(b) 我正在考虑从依赖容器获取所有服务,但 IServiceProvider 不提供获取所有服务。我只能通过接口类型来获取它们。

小智 6

尝试像这样直接注册类型

public void ConfigureServices(IServiceCollection services)
{
    // container will create the instance of this type
    services.AddScoped<ConcreteRepository>();
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以直接用

var concreteRepositoryInstance =  
         httpContext.RequestServices.GetService(typeof(ConcreteRepository))
              as IEntityOwner;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,那行得通!我还将所有带有单行的自注册存储库添加到启动类:`services.Scan(scan =&gt; scan).FromAssemblyOf&lt;ConcreteRepository&gt;().AddClasses().AsSelf().WithScopedLifetime());` (2认同)