控制域对象反转构造问题

时间:2009-12-07 09:10:46

标签: dependency-injection inversion-of-control ioc-container

据我所知,IoC-container有助于创建服务和工厂等应用程序级对象。但是应该手动创建域级对象。 Spring的手册告诉我们:“通常,不会在容器中配置细粒度的域对象,因为创建/加载域对象通常是DAO和业务逻辑的责任。”

好。但是,如果我的域“细粒度”对象依赖于某些应用程序级对象,该怎么办呢? 例如,我有一个UserViewer(用户用户,UserConstants常量)类。 用户是无法注入的域对象,但UserViewer还需要UserConstants,它是IoC-container注入的高级对象。

我想从IoC容器中注入UserConstants,但我还需要一个瞬态运行时参数User。

设计有什么问题?

提前致谢!

更新

我的问题似乎不够精确。我真正需要的是一个如何做到这一点的例子:

创建类 UserViewer(用户用户,UserService服务)的实例,其中 user 作为参数传递, service 从IoC注入

如果我注入 UserViewer查看器,那么如何将用户传递给它?

如果我手动创建 UserViewer viewer ,那么如何将 service 传递给它?

3 个答案:

答案 0 :(得分:4)

这个设计没有任何问题。你使用Factories,在域中有一条腿,在基础设施中有一条腿。

你可以手动编写它们,也可以让容器为你做这些事情,例如温莎的TypedFactoryFacility

此外,当您的域对象来自持久层时,您可以将容器插入其中以注入所需的服务(NHibernate可以这样做)。

答案 1 :(得分:1)

  

但是,如果我的域“细粒度”对象依赖于某些应用程序级对象呢?

正是这被认为是不好的做法。我想问题可能是:

  1. 这些对象数量众多,因此存在性能和内存问题。
  2. POJO风格是它们可以在所有环境中使用(持久存储在数据库中,在业务算法和规则中处理,在视图技术中读取和设置,序列化并通过网络发送)。在其中注入应用程序级对象可能会导致以下问题:

    1. 在您的体系结构中,您可能有一些规则,即某些(大多数)应用程序级对象在某些层中可用,而在其他层中则不可用。由于所有图层都可以访问pojos,因此规则将被传递过来。
    2. 在另一个JVM中进行序列化和重建时,应用程序级对象的含义是什么。它们没用,必须根据当地的等价物进行更改......

  3. 通常,构成您域名的pojos是独立的。他们可以访问其他pojos(和许多枚举),就是这样。

    除了数据之外,他们还有实现业务规则或算法细节的方法记住OO将数据和代码分组的想法; - )< / em>):

    • 当它们具有继承时,这是特别好的,因为这允许通过提供不同的实现来定制某些pojo的业务规则(不同的情况,没有if或switch:记住OO?; - )
    • 任何需要访问应用程序级对象(如访问数据库)的代码都会被取出,例如发送给服务或经理。但是该代码保持高水平,因此可读且简单,因为pojos本身负责低级细节(和特殊情况)。
        

      事实上,你经常会发现pojo方法被重用了很多,并且由服务或经理以不同的方式组成。这是减少重复的一大胜利,方法名称提供了非常需要的“含义”,并且提供了对模块新手的开发人员的更容易的访问。

答案 2 :(得分:0)

供您更新:

  

创建类UserViewer(用户用户,UserService服务)的实例,其中用户作为参数传递,服务从IoC注入。

     

如果我注入UserViewer查看器,那么如何将用户传递给它?

     

如果我手动创建UserViewer查看器,那么如何将服务传递给它呢?

在这种情况下,您需要一个工厂方法(可能在您的工厂或定位器上)。它可以看看如下,将两部分分开:

public UserViewer createUserViewer(User user) {
   UserViewer viewer = instantiateBean(UserViewer.class); 
   viewer.setUser(user);
   return viewer;
}

private <E> E instantiateBean(Class<E> clazz) {
   // call the IoC container to create and inject a bean
}