使用 .NET Core 的 DI 容器实例化对象
Instantiating objects with .NET Core's DI container
我正在使用 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
!?
有点粗糙,但这个有效
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;
}
}
如标记答案的评论中所述,您可以使用 ActivatorUtilities.CreateInstance
方法。此功能在 .NET Core 中已经存在(我相信从 1.0 版开始)。
扩展方法:
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>();
}
我正在使用 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
!?
有点粗糙,但这个有效
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;
}
}
如标记答案的评论中所述,您可以使用 ActivatorUtilities.CreateInstance
方法。此功能在 .NET Core 中已经存在(我相信从 1.0 版开始)。
扩展方法:
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>();
}