2012-11-22 81 views
2

我正在嘗試在我正在編寫的程序中使用企業庫的Unity模塊。Unity IOC和工廠模式以及存儲庫模式

但我想我使用依賴注入錯誤。我想知道是否有人能指引我走向正確的方向。

static void Main(string[] args) 
     { 
       using (IUnityContainer container = new UnityContainer()) 
       { 
        InitialiseContainer(container); 
        DataCopierFactory dcFactory = new DataCopierFactory(); 

        ERunOptions dataCopierType = ExtractParams(args); 

        IDataCopier dataCopier = dcFactory.CreateDataCopier((int)dataCopierType, container); 
        dataCopier.DetectChanges(); 
        dataCopier.ParseData(); 
        dataCopier.CopyData(); 
       } 
      } 
     } 
//use the ioc container to register the EF context type to the repository interfaces.. 
     private static void InitialiseContainer(IUnityContainer container) 
     { 

      //add Extensions: 
      container.AddNewExtension<Interception>(); 

      //Licence Schedule 
      container.RegisterType<IEFContext, LTE_DownFromWeb_EFContext>("DataCopier.ScheduleDataCopier.Source"); 
      container.RegisterType<IEFContext, LTE_Licensing_EFContext>("DataCopier.ScheduleDataCopier.Destination"); 

      container.RegisterType<IRepositorySession>("Schedule_Source",new InjectionConstructor(container.Resolve<IEFContext>("DataCopier.ScheduleDataCopier.Source"))); 
      container.RegisterType<IRepositorySession>("Schedule_Destination",new InjectionConstructor(container.Resolve<IEFContext>("DataCopier.ScheduleDataCopier.Destination"))); 



     } 

所以基本上DataCopier工廠創建像這樣一個DataCopier的一個實例:

DataCopierFactory:

//return a data copier that will transfer data from any DB to any other DB 
     public IDataCopier CreateDataCopier(int i, IUnityContainer container) 
     { 
      switch(i) 
      { 
       case 1: 
        return new ScheduleDataCopier(container); 

       default: 
        throw new InvalidOperationException("Parameter " + i + " does not exist"); 
      } 
     } 

數據複印機是這樣的:

 class ScheduleDataCopier : IDataCopier 
    { 
     private List<Site> _sites; 
     private List<SitesAndApparatuses> _scheduleList; 
     private IUnityContainer _container; 
     public ScheduleDataCopier(IUnityContainer container) 
     { 
      _container = container; 
      _scheduleList = new List<SitesAndApparatuses>(); 
     } 

     //check if new sites registration has arrived in tblSites on down from web db. 
     public bool DetectChanges() 
     { 
      using (var db = _container.Resolve<IRepositorySession>("Schedule_Source")) 
      { 
       SiteAudit lastSite = new SitesAuditRepository().GetLatest(); 
       var sitesRepo = new SitesRepository(); 
       var sites = sitesRepo.Where(x => x.SID > lastSite.SALatestSID); 

       if (sites.Count() < 1) 
       { 
        return false; 
       } 
       _sites = sites.ToList(); 
       db.Dispose(); 
      } 
      return true; 
     } 
     //parse the data into a list of object SitesAndApparatuses 
     public bool ParseData() 
     { 
      try 
      { 
       foreach (Site s in _sites) 
       { 
        var schedule = (SitesAndApparatuses)XmlObjectBuilder.Deserialize(typeof(SitesAndApparatuses), s.XMLFile); 
        schedule.acCode = s.Registration.RAcCode; 
        _scheduleList.Add(schedule); 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new NotImplementedException("HANDLE THIS SHIT!", ex); 
      } 
      return true; 
     } 

     public bool CopyData() 
     { 
      try 
      { 
       using (var db = _container.Resolve<IRepositorySession>("Schedule_Destination")) 
       { 
         var licensingScheduleRepo = new LicensingScheduleRepository(); 
         //some logic 
        db.Commit(); 
       } 
      } 
      catch (Exception ex) 
      { 
      } 
       return true; 
     } 
} 

第二個問題,我使用th在Datacopier類中解析了我的工作單元對象RepositorySession e統一容器我通過了......這是錯誤的方法,爲什麼,我努力在網上找到任何信息?

這可能是太多的代碼供人閱讀..但我希望得到答案!

在此先感謝 尼爾

回答

3

我會做這樣的事情:

container.RegisterType<IEFContext, LTE_DownFromWeb_EFContext>("Source"); 
container.RegisterType<IEFContext, LTE_Licensing_EFContext>("Destination"); 
container.RegisterType<IRepositorySession>("Source",new InjectionConstructor(new ResolvedParameter<IEFContext>("Source")); 
container.RegisterType<IRepositorySession>("Destination",new InjectionConstructor(new ResolvedParameter<IEFContext>("Destination"))); 
container.RegisterType<IDataCopier,ScheduleDataCopier>("0",new InjectionConstructor(new[] {new ResolvedParameter<IRepositorySession("Source"),new ResolvedParameter<IRepositorySesison>("Destination")})); 
//Now resolve 

ERunOptions dataCopierType = ExtractParams(args); 
IDataCopier dataCopier = container.Resolve<IDataCopier(dataCopierType.ToString()); 
dataCopier.DetectChanges(); 
dataCopier.ParseData(); 
dataCopier.CopyData(); 

DataCopier類

class ScheduleDataCopier : IDataCopier 
{ 
    private List<Site> _sites; 
    private List<SitesAndApparatuses> _scheduleList; 
    private IRepositorySession _source; 
    private (IRepositorySession _destination; 

    public ScheduleDataCopier(IRepositorySession source, (IRepositorySession destination) 
    { 
     _source=source; 
     _destination=destination; 
     _scheduleList = new List<SitesAndApparatuses>(); 
    } 

    //check if new sites registration has arrived in tblSites on down from web db. 
    public bool DetectChanges() 
    { 
     SiteAudit lastSite = new SitesAuditRepository().GetLatest(); 
     var sitesRepo = new SitesRepository(); 
     var sites = sitesRepo.Where(x => x.SID > lastSite.SALatestSID); 

     if (sites.Count() < 1) 
     { 
      return false; 
     } 
     _sites = sites.ToList(); 
     _source.DoSomething(); 
     _source.CommitAndReleaseResources();//clean up but leave object reusable 
     return true; 
    } 

    //parse the data into a list of object SitesAndApparatuses 
    public bool ParseData() 
    { 
     try 
     { 
      foreach (Site s in _sites) 
      { 
       var schedule = (SitesAndApparatuses)XmlObjectBuilder.Deserialize(typeof(SitesAndApparatuses), s.XMLFile); 
       schedule.acCode = s.Registration.RAcCode; 
       _scheduleList.Add(schedule); 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new NotImplementedException("HANDLE THIS SHIT!", ex); 
     } 
     return true; 
    } 

    public bool CopyData() 
    { 
     try 
     { 
      var licensingScheduleRepo = new LicensingScheduleRepository(); 
      //some logic 
      _desitnation.Commit(); 
     } 
     catch (Exception ex) 
     { 
      //handle exception 
     } 
     return true; 
    } 
} 

之間你做的和上面的是兩個主要差異我使用Injection Parameters(ResolvedParameter類)來在需要時動態解析對象的實例。

這使我可以讓Unity爲我完成我的整個DI流程,包括解決我的DataCopier。如果我添加其他Datacopier我只需要在新的DataCopier類型與合適的ERunOptions類型相匹配的名稱添加到Unity和我能夠與沒有改變我的代碼,以解決新DataCopier:

container.RegisterType<IDataCopier,RandomDataCopier>("0",new InjectionConstructor(new[] {new ResolvedParameter<IRepositorySession("RandomSource"),new ResolvedParameter<IRepositorySesison>("RandomDestination")})); 

和:

ERunOptions dataCopierType = ExtractParams(args); 
IDataCopier dataCopier = container.Resolve<IDataCopier(dataCopierType.ToString()); 
dataCopier.DetectChanges(); 
dataCopier.ParseData(); 
dataCopier.CopyData(); 

保持不變,但可以處理ScheduledDataCopier或RandomDataCopier

+0

太謝謝你了。只有到目前爲止,我才能得到這個答案,並且這個答覆已經解決了我在解決這個問題時遇到的不止一個問題! – niallNoigeallach