2

I am trying to use the Unity Block of the enterprise library in a program i am writing.

But i think i am using dependency injection wrong. I was wondering if some one could point me in the right direction.

    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")));



        }

So basically the DataCopier Factory creates an instance of a DataCopier like so:

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");
            }
        }

a data copier looks like this:

     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;
        }
}

Second question, i resolve my unit of work object called RepositorySession in the Datacopier classes using the unity container i passed... is this the wrong approach and why, im struggling to find any info on it online?

This is probably too much code for someone to read.. but im hoping for an answer!

Thanks in advance Neil

4

1 に答える 1

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;
    }
}

あなたが行っていることと上記の 2 つの主な違いは、必要なときにオブジェクトのインスタンスを動的に解決するためにインジェクション パラメーター(ResolvedParameter クラス) を使用していることです。

これにより、DataCopier の解決を含む、DI プロセス全体を Unity に任せることができます。別の Datacopier を追加する場合、適切な ERunOptions タイプに一致する名前で新しい DataCopier タイプを 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 を処理できます

于 2012-11-27T10:34:17.427 に答える