2011-12-02 17 views
1

我想为我的服务工厂和道工厂制造一些通用工厂,并且遇到一些限制。当需要依赖注入时,通用工厂是不可能的?

通常我的服务和DAO工厂是这样的:

public static class PersonServiceFactory 
{ 
    private static PersonService personService; 

    public static PersonService GetInstance() 
    { 
     if (personService == null) 
     { 
      PersonDao personDao = PersonDaoFactory.GetInstance(); 
      personService = new PersonService(personDao); 

     } 

     return personService; 
    } 
} 

public static class PersonDaoFactory 
{ 
    private static PersonDao personDao; 

    internal static PersonDao GetInstance() 
    { 
     if (personDao == null) 
     { 
      personDao = new PersonDao(); 

     } 

     return personDao; 
    } 
} 

然后我试图做一个普通的工厂:

public abstract class EntityDaoFactory<daoClass> 
     where daoClass : class, new() 
    { 
     private static daoClass factorySupportClass; 

     internal static daoClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       factorySupportClass = new daoClass(); 

      } 

      return factorySupportClass; 
     } 
    } 

    public abstract class EntityServiceFactory<serviceClass, daoClass> 
     where serviceClass : class, new() 
     where daoClass : class 
    { 
     private static serviceClass factorySupportClass; 

     internal static serviceClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       //daoClass daoSupportClass = *how to get daoSupportClassfactory.GetInstance(); here?* 
       factorySupportClass = new serviceClass(daoSupportClass); 

      } 

      return factorySupportClass; 
     } 
    } 

这样他们就可以像这样使用:

public static class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao> 
{ 
} 

public static class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDaoFactory> 
{ 
} 

下面是我遇到的问题:

  1. 不能使用静态类作为泛型的类型约束,我试图用于EntityServiceFactory,因为没有它,我不知道如何注入适当的dao。

  2. 不能有工厂从通用工厂得到,因为我得到一个错误,如:

静态类的Persons.PersonDaoFactory'不能 从 类型派生“Entities.EntityDaoFactory” 。 静态类必须从对象派生。

  1. 试图使他们所有的非静态类与私人建设者要解决这个问题,但后来我得到:

“Persons.PersonService”必须是一个非抽象类用为了在通用类型或方法 使用它作为参数 “服务类”公共 参数构造“Entities.EntityServiceFactory

我能读出为什么3号在这里出现,但这仍然不能解决我的问题。我得到了DaoFactory的工作,但只有在特定的DaoClass不需要任何依赖注入的情况下才有效,否则会再次弹出错误3。

反正让这些普通的工厂使用了不同的方法,同时仍然能够使用DI工作?

编辑----

我能得到这种工作的,但是它有一些古怪。首先,我创建了一个IEntityFactory接口:

public interface IEntityFactory<T> 
    where T : class 
{ 
    T GetInstance(); 
} 

再变EntityDaoFactory到:

public abstract class EntityDaoFactory<daoClass> : IEntityFactory<daoClass> 
     where daoClass : class, new() 
    { 
     private static daoClass factorySupportClass; 

     public daoClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       factorySupportClass = new daoClass(); 

      } 

      return factorySupportClass; 
     } 
    } 

所以,我可以通过在适当的类型参数,改变EntityServiceFactory到:

public abstract class EntityServiceFactory<serviceClass, daoClass, daoFactoryClass> 
     where serviceClass : class, new() 
     where daoClass : class, new() 
     where daoFactoryClass : IEntityFactory<daoClass>, new() 
    { 
     private static serviceClass factorySupportClass; 

     public static serviceClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       daoFactoryClass daoSupportFactory = new daoFactoryClass(); 
       daoClass daoSupportClass = daoSupportFactory.GetInstance(); 
       factorySupportClass = new serviceClass(); 

      } 

      return factorySupportClass; 
     } 
    } 

所以对于特定的实现,例如Person对象,调用如下所示:

public class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao> 
{ 
} 

public class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDao, PersonDaoFactory> 
{ 
} 

所以它的工作了,但怪事是:

  1. 您可以实例化一个工厂,这是必需的(?据我知道做到这一点的唯一方法)为EntityServiceFactory,但对于有人使用我的API没有理由让他们做,但他们仍然可以。

  2. 具有依赖性需求的服务和DAO现在可以实例化为不带参数,这会破坏实例化的类方法(但我必须这样做才能将其用作类型参数)。他们甚至不应该通过实例化这些对象,但他们现在可以并且不正确地这样做。

我刚刚想到的最后一个问题是,这个解决方案并没有很好地处理可变数量的依赖关系。仍然想知道是否有更好的方法呢?

结论:我认为最后,即使它工作,我放弃了很多命令,让那个通用工厂,这不灵活,并没有给我太多,所以我可能不会使用在这种情况下,由于限制。

+1

看起来像你所有的问题是因为你已经标记为静态的工厂,而且没有任何意义,而且考虑到你将使用DI来减少这种静态依赖 – sll

+2

这些与单身人士有着惊人的相似之处。 –

+1

如果您只需要构建某件东西,则无需构建工厂。 –

回答

2

首先,你是不是使用依赖注入。 Depencency injection与为泛型类/方法提供类型参数无关。

由于您违反了C#的规则,因此发生错误。你必须改变你的代码以符合它们。所以,让你的类非静态的,不要使用私有的构造函数。您可以用一个单例实例替换一个静态类,并使用受保护的构造函数来避免无控制器实例化。

+0

是的,我正在使用依赖注入,ServiceFactory在Service类的新实例中注入相应的Dao类,并且这很重要,因为我不能使用Service类作为泛型类型参数,除非它具有公共空contstructor,它我现在已经尝试过,并且能够解决我的一些问题,但现在使用我的API的人可以直接实例化一个服务(他们甚至不应该这样做),而不使用dao构造函数,这会破坏。你可能在最后一句话中提到过这个问题,但我不确定你的意思,你能举个例子吗? – SventoryMang

+0

我编辑了我的帖子,通过删除所有静态和私有构造函数,我能够完成它的工作,但是在编辑中我注意到了一些古怪的东西。 – SventoryMang

+0

标记这是一个答案,因为它解决了我的第一个问题,但它放弃了太多的值得使用它。 – SventoryMang

0

我知道这个问题真的很老,但我偶然发现了,所以我想我会给出答案。

下编译并执行你在找什么做的事:

public abstract class Entity<serviceFactory, serviceClass, daoFactory, daoClass> 
    where daoFactory : Entity<serviceFactory, serviceClass, daoFactory, daoClass>.DaoFactory, new() 
    where daoClass : class, new() 
    where serviceFactory : Entity<serviceFactory, serviceClass, daoFactory, daoClass>.ServiceFactory, new() 
    where serviceClass : class, new() 
{ 
    public abstract class DaoFactory 
    { 
     private static daoClass factorySupportClass; 

     internal static daoClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       factorySupportClass = new daoFactory().createDao(); 

      } 

      return factorySupportClass; 
     } 

     protected abstract daoClass createDao(); 
    } 

    public abstract class ServiceFactory 
    { 
     private static serviceClass factorySupportClass; 

     internal static serviceClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       daoClass daoSupportClass = DaoFactory.GetInstance(); 
       factorySupportClass = new serviceFactory().createService(daoSupportClass); 

      } 

      return factorySupportClass; 
     } 
     protected abstract serviceClass createService(daoClass dao); 
    } 
} 

现在,除非你在使用这些类型从组成根内的规划,我强烈反对这样做上述解决方案,因为你的一些依赖关系是隐藏的,更糟糕​​的是,它们固定在一组有限的参数上。相反,请尝试诸如this之类的更多DI /组合根友善解决方案。