使用.NET Core的DI容器实例化对象

ser*_*0ne 5 c# dependency-injection .net-core

我正在使用IServiceCollection来为我的对象创建所需服务的列表。现在,我想实例化一个对象,并让DI容器解析该对象的依赖关系

// In my services config.
services
    .AddTransient<IMyService, MyServiceImpl>();

// the object I want to create.
class SomeObject
{
    public SomeObject(IMyService service)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如何获得DI容器以创建类型SomeObject为注入依赖项的对象?(大概这就是对控制器的作用?)

注意:我不想存储SomeObject在服务集合中,我只想能够执行以下操作...

SomeObject obj = startup.ServiceProvider.Resolve<SomeObject>();
Run Code Online (Sandbox Code Playgroud)

...基本原理:我不必将所有控制器都添加到服务容器中,所以我也看不到为什么也必须添加SomeObject它!

kir*_*ipk 7

如对已标记答案的注释中所述,您可以使用ActivatorUtilities.CreateInstance方法。.NET Core(我认为自1.0版以来)已经存在功能

请参阅:https : //docs.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.dependencyinjection.activatorutilities.createinstance


ser*_*0ne 6

这有点粗糙,但这有效

public static class ServiceProviderExtensions
    {
        public static TResult CreateInstance<TResult>(this IServiceProvider provider) where TResult : class
        {
            ConstructorInfo constructor = typeof(TResult).GetConstructors()[0];

            if(constructor != null)
            {
                object[] args = constructor
                    .GetParameters()
                    .Select(o => o.ParameterType)
                    .Select(o => provider.GetService(o))
                    .ToArray();

                return Activator.CreateInstance(typeof(TResult), args) as TResult;
            }

            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • @flodin 我写这篇文章已经很长时间了,但是我认为这个功能已经存在。.NET Core 中的 DI 内容实现了服务定位器模式。这应该会引导你走向正确的方向...... https://joonasw.net/view/aspnet-core-di-deep-dive (2认同)
  • 好吧,但在 .NET Core 中,他们说它是: var instance = (IPipe)ActivatorUtilities.CreateInstance(serviceProvider, pipelineType); 。但是你仍然需要一个 ServiceProvider 对象:-(。我不明白为什么他们让在自己编写的类中用 DI 实例化一个类变得如此困难。 (2认同)