如何通过IoC解决循环引用?

可能重复:
依赖注入可以防止循环依赖吗?

我正在开发一个框架,它将有各种服务,如dal,与sharepoint的集成,异常处理等。

我需要在IoC中做到这一点,我对这种方法很陌生[似乎有循环参考我如何做]

所以在我看来,我们将有三种类型的项目

  • 一个界面:最好是一个单独的项目
  • 实现接口的具体类项目(像异常,dal,集成等服务项目)
  • bootstrapper conifiguration(configurator):最好是一个单独的项目,如果它驻留在“接口”项目中,它将创建具体类项目的循环引用,因为IoC需要接口和具体类的引用。
  • 现在这是事情

  • 具体类不应该引用任何其他具体类,因为这将最终创建循环引用(如果存在循环引用,或者我在这里是错误的,它是否会终止IoC的全部目的?)。

  • 其次,启动项目(单元测试,WCF服务等)应首先加载引导程序以获取所有注册的类型,因此我应该将启动项目添加到启动项目中,创建统一容器的实例[singleton]以注册所有类型。 要解决这些类型,我需要每个其他服务项目中的相同实例。

  • 所以我必须将bootstrapper项目添加到类型解析的服务项目中。 这种方法并不合适,因为它会导致与我在第1点中提到的相同的问题(每个服务项目都将包含服务项目的参考)。

    如何去做呢? 我已经尝试在注册时通过注入属性在每个具体类中添加UnityContainer作为属性。 我甚至不确定这是否正确。 我主要关心的是实现结果的最佳做法所以,如果你能指导我完成这个任务,我将非常感激......

    先谢谢你!

    你更喜欢哪种方式进行性能,配置,代码内类型注册或实例注册?

    如果需要,我可以上传演示项目。 我可以解释一件事。 Dal使用异常管理器,异常管理器为用户友好的消息使用翻译器,翻译器使用DAL获得用户友好的消息。 这是我们有循环参考的一种情况。 但如果我们相互参照,可以有很多。

    [更新 - 包括示例代码]我们还没有实现IoC,所以你不会看到任何对它的引用public bool Update(){
    布尔结果= false;

            //Central DB
            IDataServiceManager oDataServiceMgr = null;
            DbTransaction oTrans = null;
    
            //Client DB
            IDataServiceManager oDataServiceMgrClient = null;
            DbTransaction oTransClient = null;
    
            try
            {
    
                oDataServiceMgr = new DataServiceManager(); //Connets to Centeral DB
                oTrans = oDataServiceMgr.BeginTransaction();
    
                if (this.UpdateUserData(oDataServiceMgr, oTrans))  //First Update in Center
                {
                    oDataServiceMgrClient = new DataServiceManager(this.clientIDField); //Connects to client db
                    oTransClient = oDataServiceMgrClient.BeginTransaction();
                    if (this.UpdateUserData(oDataServiceMgrClient, oTransClient))
                        result = true;
                }
    
                if (result)
                {
                    oTrans.Commit(); //Center DB
                    oTransClient.Commit(); //Center DB
                }
    
    
            }
            catch (UserServiceException ex)
            {
                this._UserServiceException = new UserServiceException();
                SnapFlow.ExceptionHandling.ExceptionHandler.Wrap(this._UserServiceException, ex, true);
                throw this._UserServiceException;
            }
    
            finally 
            {
                if (!result && oTrans != null)
                    oTrans.Rollback();
    
                if (!result && oTransClient != null)
                    oTransClient.Rollback();
    
            }
    
            return result;
        }
    

    与任何循环引用一样,您需要查看代码本身的实际体系结构。 把IoC / DI放在一边,看看你的循环引用发生和重构的地方。 这些参考文献是否真的需要在那里? 有更好的设计可以使用吗?


    注意:我不太了解Unity但是我与其他ioc容器一起工作

    如果我正确地理解了你,你想知道如何布局你的项目,以避免循环引用。 在我看来,你需要这些项目(dll)

  • 包含所有接口的Waqas.Base.dll。 没有依赖团结或任何其他Waqas。*。dll
  • 一个或多个包含实现服务的dll,dal,...(即Waqas.Service.Payment.dll),它仅依赖于Waqas.Base.dll不依赖于统一
  • 一个引导程序组件(理想情况下只有一个方法)知道Waqas.Base.dll和所有其他Waqas。*。dll。 唯一的责任是连接系统。 这是知道统一性的唯一组件。
  • 您的主应用程序和您的集成测试使用引导程序。
  • 如果你有单位测试,你可以通过手动替换seriveces,dal,...来模拟测试。
  • (更新)示例

    waqas.service.payment需要在不引用引导程序或统一的情况下访问dal:

    改变形式旧版本

        public class PaymentService
        {
            public PaymentService();
    
            SavePayment( ...)
            {
                             IDAL dal = ioCContainer.resolve<IDAL>();
                             dal.Save(...);
            }
        }
    

    到新版本

        public class PaymentService
        {
            IDAL theDal;
            public PaymentService(IDAL dal) {theDal = dal;};
    
            SavePayment(...)
            {
                 theDal.Save(...);
            }
        }
    

    引导程序负责创建Dal和PaymentService并将它们相互连接。 IDal在Waqas.Base.dll中定义。

    链接地址: http://www.djcxy.com/p/96601.html

    上一篇: how to Resolve circular reference thorough IoC?

    下一篇: use of module.exports as a constructor