Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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# 如何将工厂模式用于泛型?_C#_Generics_Mvp_Factory Pattern - Fatal编程技术网

C# 如何将工厂模式用于泛型?

C# 如何将工厂模式用于泛型?,c#,generics,mvp,factory-pattern,C#,Generics,Mvp,Factory Pattern,我希望创建一个PresenterFactory,它显然将负责创建presenter实例 根据本问题中提供的代码示例: 还有@Pacane的回答,我想我会这样做: PresenterFactoryTests [TestClass] public class PresenterFactoryTests { [TestClass] public class Instance : PresenterFactoryTests { [TestMethod]

我希望创建一个PresenterFactory,它显然将负责创建presenter实例

根据本问题中提供的代码示例:

还有@Pacane的回答,我想我会这样做:

PresenterFactoryTests

[TestClass]
public class PresenterFactoryTests {
    [TestClass]
    public class Instance : PresenterFactoryTests {
        [TestMethod]
        public void ReturnsInstantialized() {                
            // arrange
            Type expected = typeof(PresenterFactory);

            // act
            PresenterFactory actual = PresenterFactory.Instance;

            // assert
            Assert.IsNotNull(actual);
            Assert.IsInstanceOfType(actual, expected);
        }

        [TestMethod]
        public void ReturnsSame() {
            // arrange
            PresenterFactory expected = PresenterFactory.Instance;

            // act
            PresenterFactory actual = PresenterFactory.Instance;

            // assert
            Assert.AreSame(expected, actual);
        }
    }

    [TestClass]
    public class Create : PresenterFactoryTests {
        [TestMethod]
        public void ReturnsAuthenticationPresenter { 
            // arrange
            Type expected = typeof(IAuthenticationPresenter);

            // act
            IAuthenticationPresenter actual = 
                PresenterFactory
                    .Instance
                    .Create<IAuthenticationPresenter, IAuthenticationView>(
                        new MembershipService());

           // assert
           Assert.IsInstanceOfType(actual, expected);
        }

        // Other tests here...
    }
}
[TestClass]
公共类PresenterFactoryTests{
[测试类]
公共类实例:PresenterFactoryTests{
[测试方法]
public void ReturnsInstantialized(){
//安排
预期类型=类型(PresenterFactory);
//表演
PresenterFactory实际值=PresenterFactory.Instance;
//断言
Assert.IsNotNull(实际值);
IsInstanceOfType(实际的,预期的);
}
[测试方法]
public void returnsName(){
//安排
PresenterFactory应为PresenterFactory.Instance;
//表演
PresenterFactory实际值=PresenterFactory.Instance;
//断言
Assert.AreName(预期、实际);
}
}
[测试类]
创建公共类:PresenterFactoryTests{
[测试方法]
public void ReturnsAuthenticationPresenter{
//安排
预期类型=类型(IAAuthenticationPresenter);
//表演
IAAuthenticationPresenter实际=
演示者工厂
.例如
.创造(
新会员服务());
//断言
IsInstanceOfType(实际的,预期的);
}
//这里还有其他测试。。。
}
}
PresenterFactory

public sealed PresenterFactory {
    private PresenterFactory() { }

    public static PresenterFactory Instance { get { return getInstance(); } }

    P Create<P, V>(params object[] args) where P : IPresenter<V> where V : IView { 
        V view = (V)Activator.CreateInstance<V>();
        return Activator.CreateInstance(typeof(P), view, args);
    }

    private static PresenterFactory getInstance() {
        if (instance == null) instance = new PresenterFactory();
        return instance;
    }

    private static PersenterFactory instance;
}
公共密封演示文稿工厂{
私有PresenterFactory(){}
公共静态PresenterFactory实例{get{return getInstance();}}
P Create(params object[]args)其中P:IPresenter其中V:IView{
V view=(V)Activator.CreateInstance();
返回Activator.CreateInstance(typeof(P),view,args);
}
私有静态PresenterFactory getInstance(){
如果(instance==null)instance=new PresenterFactory();
返回实例;
}
私有静态工厂间实例;
}
ApplicationPresenter

public class ApplicationPresenter : Presenter<IApplicationView>, IApplicationPresenter {
    public ApplicationPresenter(IApplicationView view, PresenterFactory presenters)
        : base (view) {
        Presenters = presenters;

        // other initializing stuff here...
    }      
}
公共类ApplicationPresenter:Presenter,IAApplicationPresenter{
公共应用程序演示者(IApplicationView视图,PresenterFactory演示者)
:底座(视图){
演讲者=演讲者;
//这里还有其他东西。。。
}      
}
但是,由于类型限制,我似乎无法按照上面提到的测试中的说明进行操作

在我的
PresenterFactoryTests.Create.ReturnsAuthenticationPresenter
测试方法中,当我使用接口作为类型参数时,它会编译并在运行时抛出,因为
Activator.CreateInstance
无法创建接口的实例

除此之外,如果我输入具体类型,它会抱怨无法将类型显式地转换为我的类型约束,尽管两者都实现了给定的接口

PresenterFactory
ApplicationPresenter
所必需的,我将通过其构造函数注入它,以便应用程序可以根据用户要求的功能实例化所有可用的Presenter


我缺少什么?

我认为您还需要一个通用参数-视图的具体类型,因为您需要两个具体类型(视图和演示者才能创建它们)和视图的接口类型:

P Create<P, V, IV>(params object[] args) 
      where P : IPresenter<V> where V :IV, IV: IView { 
P创建(参数对象[]args)
其中P:i表示其中V:IV,IV:IView{

我不知道您是否在使用依赖项注入器,但我个人使用Ninject及其为您生成工厂的扩展。感谢您指出Ninject。我过去已经使用过它。在您分享之前,我没有想到过它。+1感谢您提出了一个简洁的解决方案。有时更简单的解决方案是我们没有想到的至少hink.=P我担心易用性。我个人认为,对于那些可能不知道工厂如何工作的人来说,提供多类型参数对于代码重用来说已经足够容易了,因此我对注册的想法增加了使用的复杂性。我发现程序员使用多类型参数更为有价值和自然米,并在
args
对象数组中提供正确的参数。请问您对该主题有何看法?@WillMarcouiller-对于创建对象,我会使用评论中提到的DI容器。如果将其用于工厂,我不会试图花时间对代码隐藏类型,因为使用仅限于代码和“设置我的依赖项”代码往往有很多“魔力”已经存在。对于其他用途-如果编译器无法自动检测类型,我会尝试找到另一种解决方案。@WillMarcouiller注意:您可以尝试将其发布,以查看是否有更好的解决方案。我个人不喜欢您的方法没有提示参数会发生什么情况(它们是否会被传递给一个/两个/都不是类型的构造函数,是否会发生一些神奇的匹配,…)。也许使用()ViewParm(viewConstructorArgs).PresenterParm(args).Build()某些流体接口会工作得更好谢谢你对CodeReview的建议。我会提交的。由于对我的
args
没有任何线索,也许给它一个更有意义的名字,比如
PresenterCorargs
会更合适。至于DI容器,我一定会很快注意的。事实是,我现在必须催促交货=(