ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-25 17:05:59  阅读:332  来源: 互联网

标签:asp-net-core dependency-injection asp-net-core-2-0 asp-net c


我正在使用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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有