C# 如何使用具有列表的构造函数解析类<;T>;参数

C# 如何使用具有列表的构造函数解析类<;T>;参数,c#,generics,autofac,C#,Generics,Autofac,我有一个类,如下所示,构造函数接受两个List 公共类参数 { 公共列表作业{get;} 公共列表数据{get;} 公共参数(列表作业、列表数据) { Joes=Joes; Dans=Dans; } } 我尝试注册并解析此对象 static void Main(string[] args) { var builder = new ContainerBuilder(); builder.RegisterType<int>().As<object>();

我有一个类,如下所示,构造函数接受两个
List

公共类参数
{
公共列表作业{get;}
公共列表数据{get;}
公共参数(列表作业、列表数据)
{
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>>();
}
static void Main(字符串[]args)
{
var builder=new ContainerBuilder();
builder.RegisterType().As();
建造商注册通用(类型(参数));
var container=builder.Build();
var paramHaha=container.Resolve();
}
我得到了这个例外

激活特定注册时发生错误。 有关详细信息,请参见内部异常。注册:激活器=参数'1 (反射激活器),服务= [ConsoleApplication2.Param'1[[System.Int32,mscorlib,版本=4.0.0.0, 区域性=中性,PublicKeyToken=b77a5c561934e089]]],生存期= Autofac.Core.Lifetime.CurrentScopeLifetime,共享=无,所有权 =OwnedByLifetimeScope-->在类型上找不到具有“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”的构造函数 “ConsoleApplication2.Param”1[System.Int32]”可以通过调用 可用服务和参数:\r\n无法解析参数 构造函数的'System.Collections.Generic.List'1[System.Int32]joes' 'Void.ctor(System.Collections.Generic.List'1[System.Int32], System.Collections.Generic.List'1[System.Int32])。(见内文) 详细信息除外。)“}


如何解决此问题?我不关心为
Param
获取的对象是什么,也不关心
t
是什么。
Param
只是一个虚拟对象,可以在其他地方使用。但我需要正确初始化它。

为了在注册时指定参数值,您可能需要使用带参数的
方法:

builder.RegisterGeneric(typeof(Param<>))
       .As(typeof(Param<>))
       .WithParameter(new ResolvedParameter(
           (pi, ctx) => pi.Name == "joes",
           (pi, ctx) => /* Get joes with pi.ParameterType */)); 
当然,为了避免使用
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(); 
           }));
公共接口iparmprovider
{
列出GetParams();
}
公共接口iparmprovider:iparmprovider
{
列出GetParams();
}
公共类ParamProvider:iparmprovider
{
公共参数提供程序(字符串参数名)
{
这是。_paramName=paramName;
}
私有只读字符串_paramName;
//是否执行IParmProviderProvider实现
}
builder.RegisterGeneric(typeof(ParamProvider)
.As(类型(IParamProvider));
生成器注册表通用(类型(参数))
.As(类型(参数))
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType.IsGenericType
&&pi.ParameterType.GetGenericTypeDefinition()==typeof(列表),
(pi,ctx)=>{
类型t=typeof(iparmprovider).MakeGenericType(pi.ParameterType);
iparmprovider p=(iparmprovider)ctx.Resolve(t,新名称参数(“paramName”,pi.Name));
返回p.GetParams();
}));

您可以将类与参数一起注册,如下所示:

builder.RegisterGeneric(typeof(Param<>)).WithParameters(
    new [] {TypedParameter.From<object>(null), TypedParameter.From<object>(null)});
builder.RegisterGeneric(typeof(Param))。带参数(
新[]{TypedParameter.From(null),TypedParameter.From(null)});

在您的情况下,这将只作为
joes
dans
传递空值。

应该为
joes
dans
注入什么?一个随机列表?@YacoubMassad,是的。如果您不关心为这两个列表注入什么,只需为该参数创建无参数构造函数即可。@Evk,假设我无法创建参数ss构造函数。在我看来,您滥用DI容器来构建包含运行时状态的对象的对象图。这不是DI容器的用途。它们的工作是构建应用程序组件的对象图。组件是包含应用程序行为的类,而不是数据。
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(); 
           }));
builder.RegisterGeneric(typeof(Param<>)).WithParameters(
    new [] {TypedParameter.From<object>(null), TypedParameter.From<object>(null)});