代码之家  ›  专栏  ›  技术社区  ›  Jacob Poul Richardt

你如何制造一个通用工厂?

  •  3
  • Jacob Poul Richardt  · 技术社区  · 15 年前

    ServiceCall<TResult> 处理每一个电话, TResult XmlSerializer 创建返回的实例)。client类公开了一个与每个webmethod匹配的函数,该函数所要做的就是创建一个 服务呼叫<t结果> ,与 特鲁特 指定为方法的预期返回类型。 而且效果很好。

    我也在使用 Ninject 服务呼叫<t结果> .

    服务呼叫<t结果> 服务呼叫<t结果> 实例。这并不棘手,但我想让它成为一个通用工厂。意思是我想要 Factory<T<>> 哪一种方法 public T<TU> Createinstance<TU>()

    但是我不知道如何用一个类型参数创建泛型类,这个类型参数本身就是一个开放的generic。

    我正在使用依赖项的接口,但是没有必要将它们混合到这里的问题中,所以我编辑了这个问题。

    作为对Timwi的回应:
    无论如何,它也排除了静态类(因为这将是对特定类的依赖)。相反,我将指示容器(在本例中为Ninject)始终以类似于单例的行为将工厂接口的相同实例交给我。
    这就排除了 public static class Factory<T>
    建议使用一个非泛型类和一个“完全泛型”方法(如我传入的) ServiceCall<MyResult> 而不仅仅是 MyResult ),差不多就是我现在正在做的事情(减去静态类部分)。Ninject容器有一个Get方法,它的工作方式与您的第二个建议类似。
    这个问题分为两部分;首先,它使我的代码直接依赖于一个容器(Ninject),但这对我来说并不是什么大问题。让我恼火的是,如果你从外部看我的客户,你只会看到对Ninject的依赖。在运行try to make a call之前,您不会知道客户机需要注册到Ninject的ServiceCall实现才能工作。
    但是,如果客户机构造函数采用类型为Factory>的参数;,那就更清楚了。

    在任何情况下,我都会认为这是一个共同的问题,所以要么有一个共同的解决方案,要么不是一个共同的问题,我试图做一些愚蠢的事情;) 我还没有进入依赖注入,所以很可能是这样的情况。

    2 回复  |  直到 15 年前
        1
  •  4
  •   Robs Nealvs    15 年前

    这就是你想要的: Generic Factory Pattern

    namespace GenericFactoryPatternTestApp
    {
        public class Factory< T >
        {
            private readonly Dictionary< string, Type > _factoryDictionary = new Dictionary< string, Type >();
    
            public Factory()
            {    
                Type[] types = Assembly.GetAssembly(typeof (T)).GetTypes();
    
                foreach (Type type in types)
                {
                    if (!typeof (T).IsAssignableFrom(type) || type == typeof (T))
                    {
                        // Incorrect type
                        continue;
                    }
    
                    // Add the type
                    _factoryDictionary.Add(type.Name, type);
                }
            }
    
            public T Create< V >(params object[] args)
            {
                return (T) Activator.CreateInstance(_factoryDictionary[typeof (V).Name], args);
            }
        }
    }
    
        2
  •  1
  •   Timwi    15 年前

    所以如果我没听错的话,你的课看起来有点像这样:

    public static class Factory<T<>>
    {
        public static T<TU> CreateInstance<TU>() { /* ... */ }
    }
    

    var myServiceCall = Factory<ServiceCall<>>.CreateInstance<MyResult>();
    

    是什么阻止你像这样简单地宣布工厂。。。

    public static class Factory<T>
    {
        public static T CreateInstance() { /* ... */ }
    }
    

    public static class Factory
    {
        public static T CreateInstance<T>() { /* ... */ }
    }
    

    ... 然后生成这样的实例?

    var myServiceCall = Factory<ServiceCall<MyResult>>.CreateInstance();
    var myServiceCall = Factory.CreateInstance<ServiceCall<MyResult>>();