我有一个类,如下所示,构造函数有两个List<T>
public class Param<T>
{
public List<T> Joes { get; }
public List<T> Dans { get; }
public Param(List<T> joes, List<T> dans)
{
Joes = joes;
Dans = dans;
}
}
我尝试注册并解决此对象,
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<int>().As<object>();
builder.RegisterGeneric(typeof(Param<>));
var container = builder.Build();
var paramHaha = container.Resolve<Param<object>>();
}
我得到了这个例外
在激活特定注册期间发生错误。 有关详细信息,请参阅内部异常注册:Activator = Param&#39; 1 (ReflectionActivator),服务= [ConsoleApplication2.Param&#39; 1 [[System.Int32,mscorlib,Version = 4.0.0.0, Culture = neutral,PublicKeyToken = b77a5c561934e089]]],Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,Sharing = None,Ownership = OwnedByLifetimeScope ---&gt;没有任何构造函数与&#39; Autofac.Core.Activators.Reflection.DefaultConstructorFinder&#39;在类型上 &#39; ConsoleApplication2.Param&#39; 1 [System.Int32]&#39;可以用。调用 可用的服务和参数:\ r \ n无法解析参数 &#39; System.Collections.Generic.List&#39; 1 [System.Int32] joes&#39;构造函数 &#39; Void .ctor(System.Collections.Generic.List&#39; 1 [System.Int32], System.Collections.Generic.List&#39; 1 [System.Int32])&#39 ;. (见内心 详情除外。)&#34;}
如何解决此问题?我并不十分关心Param
的对象是什么,我并不关心T
是什么。 Param
只是一个在其他地方使用的虚拟对象。但我需要正确初始化它。
答案 0 :(得分:1)
为了在注册时指定参数值,您可能需要使用WithParameter
方法:
builder.RegisterGeneric(typeof(Param<>))
.As(typeof(Param<>))
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.Name == "joes",
(pi, ctx) => /* Get joes with pi.ParameterType */));
ResolveParameter
的第二个参数是一个lambda,它将给出参数的值。因为您使用Param
的通用版本,所以必须使用pi.ParameterType
属性来获取正确类型的值。
有关详细信息,请参阅Passing Parameters to Register
为了避免在依赖注入注册过程中使用joes
检索逻辑,您可以实现JoeProvider
public interface IJoeProvider
{
List<Object> GetJoes();
}
public interface IJoeProvider<T> : IJoeProvider
{
List<T> GetJoes();
}
builder.RegisterGeneric(typeof(JoeProvider<>)
.As(typeof(IJoeProvider<>));
builder.RegisterGeneric(typeof(Param<>))
.As(typeof(Param<>))
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.Name == "joes",
(pi, ctx) => {
Type t = typeof(IJoeProvider<>).MakeGenericType(pi.ParameterType);
IJoeProvider p = (IJoeProvider)ctx.Resolve(t);
return p.GetJoes();
}));
当然,为了避免使用JoeProvider
和DanProvider
,您只能拥有一个Provider
并使用参数解析它。
public interface IParamProvider
{
List<Object> GetParams();
}
public interface IParamProvider<T> : IParamProvider
{
List<T> GetParams();
}
public class ParamProvider<T> : IParamProvider<T>
{
public ParamProvider(String paramName)
{
this._paramName = paramName;
}
private readonly String _paramName;
// Do IParamProviderProvider implementation
}
builder.RegisterGeneric(typeof(ParamProvider<>)
.As(typeof(IParamProvider<>));
builder.RegisterGeneric(typeof(Param<>))
.As(typeof(Param<>))
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.ParameterType.IsGenericType
&& pi.ParameterType.GetGenericTypeDefinition() == typeof(List<>),
(pi, ctx) => {
Type t = typeof(IParamProvider<>).MakeGenericType(pi.ParameterType);
IParamProvider p = (IParamProvider)ctx.Resolve(t, new NamedParameter("paramName", pi.Name));
return p.GetParams();
}));
答案 1 :(得分:1)
您可以将类与参数一起注册,如下所示:
builder.RegisterGeneric(typeof(Param<>)).WithParameters(
new [] {TypedParameter.From<object>(null), TypedParameter.From<object>(null)});
这只会在您的情况下将空值作为joes
和dans
传递。