Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Castle windsor类型化工厂-使用运行时类型作为参数解析泛型服务_C#_Generics_Castle Windsor - Fatal编程技术网

C# Castle windsor类型化工厂-使用运行时类型作为参数解析泛型服务

C# Castle windsor类型化工厂-使用运行时类型作为参数解析泛型服务,c#,generics,castle-windsor,C#,Generics,Castle Windsor,我有一个使用此方法的类型化工厂: IRepository<T> Get<T>() where T : class IRepository Get()其中T:class 和以下组件类型选择器: public class RepositoryComponentSelector : DefaultTypedFactoryComponentSelector { protected override string GetComponentName(Met

我有一个使用此方法的类型化工厂:

IRepository<T> Get<T>() where T : class
IRepository Get()其中T:class
和以下组件类型选择器:

public class RepositoryComponentSelector : DefaultTypedFactoryComponentSelector
    {
        protected override string GetComponentName(MethodInfo method, object[] arguments)
        {
            return ComponentNames.Repository;
        }

        protected override Type GetComponentType(MethodInfo method, object[] arguments)
        {
               return typeof(Repository<>).MakeGenericType(method.GetGenericArguments()[0]);
        }
    }
公共类RepositoryComponentSelector:DefaultTypedFactoryComponentSelector
{
受保护的重写字符串GetComponentName(MethodInfo方法,对象[]参数)
{
返回ComponentNames.Repository;
}
受保护的重写类型GetComponentType(MethodInfo方法,对象[]参数)
{
返回typeof(Repository).MakeGenericType(方法.GetGenericArguments()[0]);
}
}
但是,我希望有一个返回存储库的工厂实现,但只需要指定类型为的参数,而不是编译时类型的参数

示例(无效代码)-我希望T是提供的类型

IRepository<T> Get(Type type);
i存储获取(类型);
我知道这不会编译,因为方法本身必须是泛型的,但我事先不知道参数

我试图实现的是简化此模式:

if (documentType == SomeEnum.x)
{
    this.RepositoryFactory.Get<X>().Update(document as X);
}
else if (documentType == SomeEnum.y)
{
    this.RepositoryFactory.Get<Y>().Update(document as Y);
}
else if (documentType == SomeEnum.z)
{
    this.RepositoryFactory.Get<Z>().Update(document as Z);
}
if(documentType==SomeEnum.x)
{
this.RepositoryFactory.Get().Update(文档为X);
}
else if(documentType==SomeEnum.y)
{
this.RepositoryFactory.Get().Update(文档为Y);
}
else if(documentType==SomeEnum.z)
{
this.RepositoryFactory.Get().Update(文档为Z);
}
通过基于枚举(或该枚举返回类型的扩展)解析工厂


有没有办法通过Castle Windsor或其他我可以采取的方法来实现这一点?

我认为这更多是关于多态性和一般调度问题,而不是将其挂接到容器中

您可以使用双重分派方法:

public void Save(DocumentBase document)
{
    var dispatcher = new DocumentDispatcher();
    document.Accept(dispatcher);
}

public abstract class DocumentBase
{
    public abstract void Accept(IDocumentDispatcher dispatcher);
}

public class DocumentA : DocumentBase
{
    public override void Accept(IDocumentDispatcher dispatcher)
    {
        dispatcher.Dispatch(this);
    }
}

public class DocumentB : DocumentBase
{
    public override void Accept(IDocumentDispatcher dispatcher)
    {
        dispatcher.Dispatch(this);
    }
}

public interface IDocumentDispatcher
{
    void Dispatch(DocumentA document);

    void Dispatch(DocumentB document);
}

public class DocumentDispatcher : IDocumentDispatcher
{
    public void Dispatch(DocumentA document)
    {
        this.RepositoryFactory.Get<DocumentA>().Update(document);
    }

    public void Dispatch(DocumentB document)
    {
        this.RepositoryFactory.Get<DocumentB>().Update(document);
    }
}
公共作废保存(DocumentBase文档)
{
var dispatcher=newdocumentdispatcher();
文件接收(调度员);
}
公共抽象类文档库
{
公共摘要无效接受(IDocumentDispatcher);
}
公共类文档:文档库
{
公共覆盖无效接受(IDocumentDispatcher)
{
调度员。调度(本);
}
}
公共类DocumentB:DocumentBase
{
公共覆盖无效接受(IDocumentDispatcher)
{
调度员。调度(本);
}
}
公共接口IDocumentDispatcher
{
无效派送(文件);
无效派送(文件B文件);
}
公共类DocumentDispatcher:IDocumentDispatcher
{
公共无效调度(文件文件)
{
this.RepositoryFactory.Get().Update(文档);
}
公共无效调度(文件B文件)
{
this.RepositoryFactory.Get().Update(文档);
}
}
或者,您可以使用动态分派:

public void Save(DocumentBase document)
{
    var dispatcher = new DocumentDispatcher();
    dispatcher.Dispatch((dynamic)document);
}

public class DocumentDispatcher : IDocumentDispatcher
{
    public void Dispatch<T>(T document)
    {
        this.RepositoryFactory.Get<T>().Update(document);
    }
}
public void Save(DocumentBase document)
{
    var actions = new Dictionary<Type, Action<DocumentBase>>
                      {
                          { typeof(DocumentA), d => this.RepositoryFactory.Get<DocumentA>().Update((DocumentA)d) },
                          { typeof(DocumentB), d => this.RepositoryFactory.Get<DocumentB>().Update((DocumentB)d) },
                      };

    actions[typeof(DocumentBase)](document);
}
公共作废保存(DocumentBase文档)
{
var dispatcher=newdocumentdispatcher();
调度员.调度((动态)文件);
}
公共类DocumentDispatcher:IDocumentDispatcher
{
公共无效调度(T文件)
{
this.RepositoryFactory.Get().Update(文档);
}
}
甚至字典发送:

public void Save(DocumentBase document)
{
    var dispatcher = new DocumentDispatcher();
    dispatcher.Dispatch((dynamic)document);
}

public class DocumentDispatcher : IDocumentDispatcher
{
    public void Dispatch<T>(T document)
    {
        this.RepositoryFactory.Get<T>().Update(document);
    }
}
public void Save(DocumentBase document)
{
    var actions = new Dictionary<Type, Action<DocumentBase>>
                      {
                          { typeof(DocumentA), d => this.RepositoryFactory.Get<DocumentA>().Update((DocumentA)d) },
                          { typeof(DocumentB), d => this.RepositoryFactory.Get<DocumentB>().Update((DocumentB)d) },
                      };

    actions[typeof(DocumentBase)](document);
}
公共作废保存(DocumentBase文档)
{
var actions=新字典
{
{typeof(DocumentA),d=>this.RepositoryFactory.Get().Update((DocumentA)d)},
{typeof(DocumentB),d=>this.RepositoryFactory.Get().Update((DocumentB)d)},
};
行动[类型(文档库)](文档);
}

我更喜欢第一种解决方案,因为它只是一种类型安全的解决方案。

我认为双调度方法在这种情况下不可用。我没有继承层次结构,只是根据一个枚举来决定。我也不喜欢所有额外的样板代码。字典分派可以工作,但仅适用于操作方法。如果它是一个Func,那么我的位置和以前一样——我必须让方法返回对象,然后将其强制转换,对吗?后续评论:我误解了双重分派方法。这对我有用。然而,我仍然不喜欢所有额外的样板。此外,在我看来,这样我使我的POCO对象具有依赖性(仅通过一个参数,但仍然)。@FreHu,如果第一个解决方案有效,那么第二个解决方案也会有效……代码更少,无需在POCO对象上添加任何方法,但类型安全性更低。如果你不喜欢额外的编码,你无论如何都会有问题。我觉得创建一些Castle boiler plate代码,比如你的
RepositoryComponentSelector
更糟糕。关于您的POCO问题,类将只依赖于您的接口,而不是具体的接口。没有实际理由认为这会成为一个问题。