使用已知服务实例化未注册的服务(通过ctr注入它们)。
我想避免容器污染。
答案 0 :(得分:7)
以下是从容器中解析未注册的具体类型的另一种方法。请注意,所有autofac构造函数都在查找和选择逻辑,所有注册事件处理程序仍然有效。
首先,您定义此方法:
public static object ResolveUnregistered(this IComponentContext context, Type serviceType, IEnumerable<Parameter> parameters)
{
var scope = context.Resolve<ILifetimeScope>();
using (var innerScope = scope.BeginLifetimeScope(b => b.RegisterType(serviceType)))
{
IComponentRegistration reg;
innerScope.ComponentRegistry.TryGetRegistration(new TypedService(serviceType), out reg);
return context.ResolveComponent(reg, parameters);
}
}
我们的想法是从派生的上下文中获取组件注册,并在当前上下文中解析它。 然后你可以创建一些方便的重载:
public static object ResolveUnregistered(this IComponentContext context, Type serviceType)
{
return ResolveUnregistered(context, serviceType, Enumerable.Empty<Parameter>());
}
public static object ResolveUnregistered(this IComponentContext context, Type serviceType, params Parameter[] parameters)
{
return ResolveUnregistered(context, serviceType, (IEnumerable<Parameter>)parameters);
}
public static TService ResolveUnregistered<TService>(this IComponentContext context)
{
return (TService)ResolveUnregistered(context, typeof(TService), Enumerable.Empty<Parameter>());
}
public static TService ResolveUnregistered<TService>(this IComponentContext context, params Parameter[] parameters)
{
return (TService)ResolveUnregistered(context, typeof(TService), (IEnumerable<Parameter>)parameters);
}
答案 1 :(得分:3)
我找到了一个需要一些自定义代码的解决方案。某些事情是我的应用程序特有的,但我认为你可以得到图片。
Resolve(parameter.ParameterType)将是对您的容器的调用。
public object ResolveUnregistered(Type type)
{
var constructors = type.GetConstructors();
foreach (var constructor in constructors)
{
try
{
var parameters = constructor.GetParameters();
var parameterInstances = new List<object>();
foreach (var parameter in parameters)
{
var service = Resolve(parameter.ParameterType);
if (service == null) throw new NopException("Unkown dependency");
parameterInstances.Add(service);
}
return Activator.CreateInstance(type, parameterInstances.ToArray());
}
catch (NopException)
{
}
}
throw new NopException("No contructor was found that had all the dependencies satisfied.");
}
答案 2 :(得分:0)
这是一种使用已知构造函数(ctor)属性解析未注册类型的方法。这是基于先前的一篇精彩文章:https://stackoverflow.com/a/6994144/2641447。 在此解决方案中,由Autofac处理构造函数查找和选择逻辑绝对很棒。
引用该注释是为了处理我通过配置组件来解决的'ExternallyOwned()'问题,从而使实例永远不会被容器处理。
我认为该解决方案的改进可能是:
public static object ResolveUnregistered(this IComponentContext context, Type serviceType, IEnumerable<Parameter> parameters)
{
var scope = context.Resolve<ILifetimeScope>();
using (var innerScope = scope.BeginLifetimeScope(b => b.RegisterType(serviceType).ExternallyOwned()))
return innerScope.Resolve(serviceType, parameters);
}
用法:
using Autofac;
using Autofac.Core;
using System;
using System.Collections.Generic;