IoC 컨테이너 (Unity)를 사용하여 인터페이스를 등록하고 개체를 확인/인스턴스화합니다.IoC 디자인 - 동적 위임 서비스 용 서비스 내 참조 서비스 로케이터
잘 작동하고 인터페이스에 종속 된 모든 클래스가 생성자에 삽입되지만 디자인 문제가 발생합니다.
특정 시간에 등록 된 대리자를 호출하는 CronJob 서비스가 있으며 서비스 로케이터에 의해 인스턴스화됩니다.
작업을 등록 할 수 있기 때문에 서비스 로케이터 Unity 컨테이너를 인스턴스화 된 클래스 내에서 참조하고 있습니다. 작업을 동적으로 등록 할 수 있기 때문에 컴파일 타임에 어떤 객체가 생성자에 전달 될지 모르기 때문에이 작업을 수행하고 있습니다. .
비록 IoC와 통합에 익숙하지 않지만 서비스 내에서 정적 서비스 로케이터를 참조하는 것이 좋지 않기 때문에 모든 종속성을 생성자에 전달해야합니다. 다른 방법에 대한 생각을 고맙게 생각합니다. 이 경우 서비스 로케이터를 참조하는 것이 좋습니까?
감사합니다,
크리스
코드는 다음과 같습니다 : 유니티를 사용
서비스 로케이터
// 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();
}
}