繁体   English   中英

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

[英]ASP.NET Core 2.0 Dependency Injection default instance

我正在使用ASP.NET Core 2.0Microsoft.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>();
        ...
    }
}

我想只有指定IMyToolGeneralMyToolGeneralIOtherOther ,但MyObject不行,因为我有很多课是这样的(验证者,帮助者,......),我并不需要指定这些。

我怎么能在ASP.NET Core 2.0做到这一点?

编辑

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

编辑II我重写类并在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);
}

如果您不想注册所有类型,还可以做一件事。 还有的活化剂公用事业它提供了一种方法来构造未在容器中注册自己类型的对象,但需要将构建容器的依赖。 您可以使用ActivatorUtilities.CreateInstance方法创建对象。 例如,使用服务定义,您可以创建一个MyObject实例,如下所示:

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

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

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

因此,您无法通过依赖项注入创建MyService对象,因为它的依赖项MyObject未注册。 如果您希望DI框架为您自动实例化对象,则必须注册它。

您可以将它们添加到DI via

services.AddScoped<MyObject>();

或者更复杂的东西

services.AddScoped(provider =>
{
    var res = new MyObject
    {
        Message = "Hello World 2"
    };
    return res;
});

你可以在哪里构建对象。

这里有样品prj

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM