用.net Core's DI容器实例化对象

本文关键字:DI 实例化 对象 net Core | 更新日期: 2023-09-27 18:15:32

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

// In my services config.
services
    .AddTransient<IMyService, MyServiceImpl>();
// the object I want to create.
class SomeObject
{
    public SomeObject(IMyService service)
    {
        ...
    }
}

我如何得到DI容器创建类型SomeObject的对象,与依赖注入?

注意:我不想在服务集合中存储SomeObject,我只是希望能够做这样的事情…

SomeObject obj = startup.ServiceProvider.Resolve<SomeObject>();

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

用.net Core's DI容器实例化对象

如已标记答案的评论所述,您可以使用ActivatorUtilities.CreateInstance方法。这个功能在。net Core中已经存在了(我相信从1.0版本开始)。

见:https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.activatorutilities.createinstance

这有点粗糙,但这是可行的

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;
        }
    }

扩展方法:

public static class Extensions
{
    public static T BuildObject<T>(this IServiceProvider serviceProvider, params object[] parameters)
        => ActivatorUtilities.CreateInstance<T>(serviceProvider, parameters);
}

用法:

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    var ss = HttpContext.RequestServices.BuildObject<SomeService>();
}