CSharp - IoC设计参考服务定位器,用于动态代理服务

  显示原文与译文双语对照的内容
0 0

我使用IoC容器( Unity ) 来 register 接口,并解析/实例化对象。

它工作得很好,所有具有接口依赖性的类都被注入到构造函数中。

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

因为作业可以以注册,所以我在编译时将服务定位器的be容器引用。

尽管我认为在服务中引用 static 服务定位器是很不好的,所有的相关性都应该在这种情况下。

谢谢,

克里斯

代码如下:

使用统一的服务定位器

//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());
 }
}

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();
 }
}
时间:原作者:1个回答

0 0

可以注入一个工厂,然后解析ISynchronisationService实例,调用容器,就像你在SyncRecords中所做的。

在实现工厂方法的例子中,请参见这里的,其中有几个。

原作者:
...