Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IoC设计-动态代理服务的服务内参考服务定位器_C#_.net_Inversion Of Control_Ioc Container - Fatal编程技术网

C# IoC设计-动态代理服务的服务内参考服务定位器

C# IoC设计-动态代理服务的服务内参考服务定位器,c#,.net,inversion-of-control,ioc-container,C#,.net,Inversion Of Control,Ioc Container,我使用IoC容器(Unity)来注册接口和解析/实例化对象 它工作正常,所有依赖于接口的类都被注入到构造函数中,但是我遇到了一个设计问题 我有一个CronJob服务,它在特定时间调用注册的委托,它也由服务定位器实例化 因为可以注册作业,所以我从实例化的类中引用服务定位器Unity容器,因为我不知道在编译时哪些对象将被传递到构造函数中,因为作业可以动态注册 然而,尽管我对IoC和unity还不熟悉,但据我所知,从服务中引用静态服务定位器是不好的,所有依赖项都应该在构造函数中传递——因此我希望能够考

我使用IoC容器(Unity)来注册接口和解析/实例化对象

它工作正常,所有依赖于接口的类都被注入到构造函数中,但是我遇到了一个设计问题

我有一个CronJob服务,它在特定时间调用注册的委托,它也由服务定位器实例化

因为可以注册作业,所以我从实例化的类中引用服务定位器Unity容器,因为我不知道在编译时哪些对象将被传递到构造函数中,因为作业可以动态注册

然而,尽管我对IoC和unity还不熟悉,但据我所知,从服务中引用静态服务定位器是不好的,所有依赖项都应该在构造函数中传递——因此我希望能够考虑其他方法来实现这一点,或者在这种情况下引用服务定位器可以吗

谢谢

克里斯

代码如下:

使用Unity的服务定位器

// ServiceManager provides service location facilities, logging facilities, and database access via IUnitOfWork interface
public class ServiceManager
{
    private static readonly UnityContainer m_ServicesContainer = new UnityContainer();
    private static readonly ServiceManager m_Manager = new ServiceManager();
    public static ServiceManager Instance { get { return m_Manager; } }
    private ILogger Logger { get { return Resolve<ILogger>(); } }

    public T Resolve<T>()
    {
        return m_ServicesContainer.Resolve<T>();
    }

    private ServiceManager()
    {
        // register the unit of work class first!!
        RegisterType<IUnitOfWork, UnitOfWork>();
        // always register the logger (without logging)
        RegisterType<ILogger, NLogForEntityFrameworkLogger>(true);
        // always register the settings manager (without logging)
        RegisterType<ISettingsService, SettingsService>();
        RegisterType<IPluginManagerService, PluginManagerService>(true);
        RegisterType<ICronJobService, CronJobService>(true);
        RegisterType<IReminderGeneratorService, ReminderGeneratorService>();
        RegisterType<IInvoiceService, InvoiceService>();
    }

    public void RegisterType<TFrom, TTo>(bool isSingleton = false)
    {
         if (isSingleton == false)
            m_ServicesContainer.RegisterType(typeof(TFrom), typeof(TTo));
        else
            m_ServicesContainer.RegisterType(typeof(TFrom), typeof(TTo), new ContainerControlledLifetimeManager());

    }
}
//ServiceManager通过IUnitOfWork接口提供服务位置工具、日志记录工具和数据库访问
公共类服务管理器
{
私有静态只读UnityContainer m_ServicesContainer=新UnityContainer();
私有静态只读ServiceManager m_Manager=新ServiceManager();
公共静态ServiceManager实例{get{return m_Manager;}}
专用ILogger记录器{get{return Resolve();}}
公共事务解决方案
{
返回m_ServicesContainer.Resolve();
}
私人服务经理()
{
//先注册工作班的单位!!
RegisterType();
//始终注册记录器(不记录日志)
RegisterType(true);
//始终注册设置管理器(不记录日志)
RegisterType();
RegisterType(true);
RegisterType(true);
RegisterType();
RegisterType();
}
公共无效注册表类型(bool-isSingleton=false)
{
如果(isSingleton==false)
m_ServicesContainer.RegisterType(类型of(TFrom),类型of(TTo));
其他的
m_ServicesContainer.RegisterType(typeof(TFrom)、typeof(TTo)、新的ContainerControlled LifetimeManager();
}
}
CronJob类

public static class CronJobDelegates
{
    public static void SyncRecords(BusinessUnit businessUnit)
    {
        ISynchronisationService syncService = ServiceManager.Instance.Resolve<ISynchronisationService>();
        syncService.Sync(businessUnit);
    }
}

class CronJobService : ServiceBaseWithUnitOfWork, ICronJobService
{
    public CronJobService(IUnitOfWork unitOfWork, ILogger logger, ISettingsService settings)
        : base(unitOfWork, logger)
    {
        m_Settings = settings;
        RegisterCronJob("SyncAccountRecords", CronJobDelegates.SyncRecords,"*1****");
    }

    ISettingsService m_Settings;

    public class RegisteredCronJob
    {
        public RegisteredCronJob(string jobName, EventJobDelegate job)
        {
            JobName = jobName;
            Job = job;
        }

        public string JobName { get; private set; }
        public EventJobDelegate Job { get; private set; }
    }

    static object Lock = new object();

    Dictionary<string, EventJobDelegate> CronJobs = new Dictionary<string, EventJobDelegate>();

    public void RegisterCronJob(string jobName, EventJobDelegate jobCallback, string jobSetting)
    {
        lock(Lock)
        {
            if(CronJobs.ContainsKey(jobName))
            {
                LogMessage("Job '" + jobName + "' already registered", LogLevel.Warn);
                // warning job already registered
            }
            else
            {
                CronJob cronJobRecord = UnitOfWork.CronJobRepository.GetByID(jobName);

                if (cronJobRecord == null)
                {
                    CronJob newCronJob = new CronJob()
                    {
                        JobName = jobName,
                        JobSetting = jobSetting
                    };
                    UnitOfWork.CronJobRepository.Insert(newCronJob);
                }
                else
                    jobSetting = cronJobRecord.JobSetting;

                LogMessage("Job '" + jobName + "' registered using settings: " + jobSetting + ". Next run due on UTC " + NCrontab.CrontabSchedule.Parse(jobSetting).GetNextOccurrence(DateTime.UtcNow), LogLevel.Info);

                CronJobs.Add(jobName, jobCallback);
                UnitOfWork.Save();
            }
        }
    }

    public void ProcessEvents()
    {
        foreach(BusinessUnit businessUnit in UnitOfWork.BusinessUnitRepository.Get())
        {
            foreach (CronJob cronJob in UnitOfWork.CronJobRepository.Get())
            {
                lock(Lock)
                {
                    NCrontab.CrontabSchedule schedule = NCrontab.CrontabSchedule.Parse(cronJob.JobSetting);

                    if (schedule.GetNextOccurrence(cronJob.LastRan) > DateTime.UtcNow.AddHours(businessUnit.GmtOffset))
                    {
                        EventJobDelegate jobDelegate;
                        if (CronJobs.TryGetValue(cronJob.JobName, out jobDelegate) == true )
                        {
                            jobDelegate(businessUnit);
                            cronJob.LastRan = DateTime.UtcNow;
                            UnitOfWork.CronJobRepository.Update(cronJob);
                            LogMessage("Job '" + cronJob.JobName + "' ran, next schedule on " + schedule.GetNextOccurrence(cronJob.LastRan));
                        }
                    }
                }
            }
        }
        UnitOfWork.Save();
    }
}
公共静态类CronJobDelegates
{
公共静态无效同步记录(业务单元业务单元)
{
ISynchronisationService-syncService=ServiceManager.Instance.Resolve();
syncService.Sync(业务单元);
}
}
类CronJobService:ServiceBaseWithUnitOfWork,MicronJobService
{
公共CronJobService(IUnitOfWork、ILogger记录器、ISettingsService设置)
:底座(工作单元、记录器)
{
m_设置=设置;
RegisterCronJob(“SyncAccountRecords”,CronJobDelegates.SyncRecords,“*1****”);
}
i设置服务m_设置;
公共类RegisteredCronJob
{
公共RegisteredCronJob(字符串jobName,EventJobDelegate job)
{
JobName=JobName;
工作=工作;
}
公共字符串JobName{get;private set;}
public EventJobDelegate作业{get;private set;}
}
静态对象锁=新对象();
Dictionary CronJobs=新字典();
public void RegisterCronJob(字符串jobName、EventJobDelegate jobCallback、字符串jobSetting)
{
锁(锁)
{
if(CronJobs.ContainsKey(jobName))
{
LogMessage(“作业”’+jobName+“‘已注册’”,LogLevel.Warn);
//警告作业已注册
}
其他的
{
CronJob cronJobRecord=UnitOfWork.CronJobRepository.GetByID(作业名称);
if(cronJobRecord==null)
{
CronJob newCronJob=new CronJob()
{
JobName=JobName,
作业设置=作业设置
};
UnitOfWork.CronJobRepository.Insert(newCronJob);
}
其他的
jobSetting=cronJobRecord.jobSetting;
LogMessage(“作业”“+jobName+””使用设置注册:“+jobSetting+”。下一次运行将在UTC“+nContab.CrontabSchedule.Parse(jobSetting).GetNextOccurrence(DateTime.UtcNow),LogLevel.Info”到期;
添加(jobName,jobCallback);
UnitOfWork.Save();
}
}
}
public void ProcessEvents()
{
foreach(UnitOfWork.BusinessUnitRepository.Get()中的BusinessUnit BusinessUnit)
{
foreach(UnitOfWork.CronJobRepository.Get()中的CronJob CronJob)
{
锁(锁)
{
ncontab.CrontabSchedule schedule=ncontab.CrontabSchedule.Parse(cronJob.JobSetting);
if(schedule.GetNextOccurrence(cronJob.LastRan)>DateTime.UtcNow.AddHours(businessUnit.GmtOffset))
{
EventJobDelegate jobDelegate;
if(CronJobs.TryGetValue(cronJob.JobName,out jobDelegate)==true)
{
工作代表(业务单位);
cronJob.LastRan=DateTime.UtcNow;
UnitOfWork.CronJobRepository.Update(cronJob);
日志消息(“Job'”+cronJob.JobName+“”已运行,下一个计划位于“+schedule.GetNextOccurrence(cronJob.LastRan));
}
}
}
}
}
UnitOfWork.Save();
}
}

您可以注入一个工厂,然后像在SyncRecords中一样解析调用容器的ISynchronisationService实例

有关实施工厂方法的示例