编程语言
首页 > 编程语言> > c#-ASP.NET Core 2.0依赖注入默认实例

c#-ASP.NET Core 2.0依赖注入默认实例

作者:互联网

我正在使用ASP.NET Core 2.0和Microsoft.Extensions.DependencyInjection.我有一些我不想指定其实现或不需要指定的类.

例如:

public interface IMyService
{
    void WriteSomething();
}

public class MyService : IMyService
{
    private readonly MyObject myObject;

    public MyService(MyObject myObject)
    {
        this.myObject = myObject;
    }

    public void WriteSomething()
    {
        this.myObject.Write();
    }
}

public interface IOther
{
    string GetName();
}

public class Other : IOther
{
    public string GetName()
    {
        return "james bond";
    }
}

public class MyObject
{
    private readonly IOther other;

    public MyObject(IOther other)
    {
        this.other = other;
    }

    public void Write()
    {
        Console.WriteLine(string.Concat("hi ", this.other.GetName()));
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddScoped<IOther, Other>();
        services.AddScoped<IMyService, MyService>();
        ...
    }
}

而且我只想用MyToolGeneral指定IMyToolGeneral,用Other指定IOther,而不能指定MyObject,因为我有很多这样的类(验证器,帮助器…),我不需要指定这些.

如何在ASP.NET Core 2.0中做到这一点?

编辑

我需要ASP.NET Core 2.0 DI可以注入MyObject的实例,而无需在DI配置中指定它. MyObject没有基类的合同(接口),并且其构造函数中的所有参数都在DI配置中指定.

编辑二
我重写了类,并在Unity中包含一个示例(有效)和在MS DI中包含相同的示例(不起作用)

团结的榜样(工作)

class Program
{
    static void Main(string[] args)
    {
        var container = UnityConfig();

        var service = container.Resolve<IMyService>();

        service.WriteSomething();

        Console.ReadKey();
    }

    static UnityContainer UnityConfig()
    {
        var container = new UnityContainer();

        container.RegisterType<IMyService, MyService>();

        container.RegisterType<IOther, Other>();

        return container;
    }
}

MS DI(无效)
未处理的异常:System.InvalidOperationException:尝试激活“ ConsoleDI.MyService”时,无法解析类型为“ ConsoleDI.MyObject”的服务.

class Program
{
    static void Main(string[] args)
    {
        var serviceProvider = new ServiceCollection()
                .AddTransient<IMyService, MyService>()
                .AddTransient<IOther, Other>()
                .BuildServiceProvider();

        var service = serviceProvider.GetService<IMyService>();

        service.WriteSomething();

        Console.ReadKey();
    }
}

解决方法:

内置的依赖项注入容器Microsoft.Extensions.DependencyInjection不支持基于约定的注册.因此,当您通常会设置一些约定时,例如命名空间中的所有类型都将被注册为临时依赖项,这对于标准容器来说是无法立即使用的.

如果仍要执行此操作,则必须将依赖项注入容器更改为功能更强大的容器(请记住,内置容器是设计得非常苗条的容器),或者创建自己的基于约定的逻辑来注册您的依赖性.例如,您可以简单地循环遍历当前程序集,并检查特定名称空间中的所有类型并注册这些类型:

var types = Assembly.GetExecutingAssembly()
    .GetTypes()
    .Where(t => t.Namespace == "Your.Custom.Namespace");

foreach (var type in types)
{
    services.AddTransient(type);
}

如果您不想注册所有类型,可以做一件事.有activator utilities提供了一种构造类型的对象的方法,这些对象本身没有在容器中注册,但是需要构造容器的依赖项.您可以使用ActivatorUtilities.CreateInstance方法创建一个对象.例如,使用服务定义,您可以创建一个MyObject实例,如下所示:

var myObject = ActivatorUtilities.CreateInstance<MyObject>(serviceCollection);

这将自动从容器中获取IOther并将其注入MyObject的构造函数中. MyObject不需要为此注册,但IOther需要注册.

因此,这仅适用于实例化未在容器中注册的类型.它不适用于其他类型所需的依赖项.依赖项注入只能为在依赖项注入容器中注册的那些依赖项自动提供实例.

因此,由于未注册依赖项MyObject,因此无法通过依赖项注入创建MyService对象.无法解决此问题,如果要让DI框架自动为您实例化对象,则必须注册它.

标签:asp-net-core,dependency-injection,asp-net-core-2-0,asp-net,c
来源: https://codeday.me/bug/20191025/1930090.html