Ninject Conditional Self bind to change scope (Для Task-планировщика) не работает должным образом?
В веб-приложении MVC привязка DbContext правильно работает сInRequestScope()
kernel.Bind<DbContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork<DbContext>>().To<UnitOfWork<DbContext>>();
Но изДиспетчер задач вызовDbContext
вInRequestScope()
невозможно обновить таблицу базы данных (без ошибок), пока я не поменяю Binding наInSingletonScope()
ИЛИ ЖЕInThreadScope()
Вопрос: Так что их любой способ изменить сферу наInSingletonScope()
/ InThreadScope()
для вызова планировщика заданий.?
// ЗаДиспетчер задач Звоните, я пробовал нижепривязанный, но не работает должным образом
kernel.Bind<DbContext>().ToSelf()
.When(request => request.Target.Type.Namespace.StartsWith("NameSpace.ClassName"))
.InSingletonScope();
** И, наверное, я что-то упускаю. Нужна помощь.
Обновлен фрагмент кода
#region Commented Code
public EmailTask() : this
( DependencyResolver.Current.GetService<IMessageManager>(),
, DependencyResolver.Current.GetService<IUnitOfWork<DbContext>>()) { }
#endregion
public EmailTask(IMessageManager messageManager, IUnitOfWork<DbContext> unitOfWork)
{
this._messageManager = messageManager;
this._unitOfWork = unitOfWork;
ProcessEmail();
}
public class NonRequestScopedParameter : IParameter { ... }
public void ProcessEmail()
{
var temp = SomeRepository.GetAll();
SendEmail(temp);
temp.Date = DateTime.Now;
SomeRepository.Update(temp);
unitOfWork.Commit();
}
public class ExecuteEmailTask : ITask
{
private readonly IResolutionRoot _resolutionRoot;
private int _maxTries = 5;
public ExecuteEmailTask(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}
public void Execute(XmlNode node)
{
XmlAttribute attribute1 = node.Attributes["maxTries"];
if (attribute1 != null && !String.IsNullOrEmpty(attribute1.Value))
{
this._maxTries = int.Parse(attribute1.Value);
}
/// send email messages
var task = _resolutionRoot.Get<EmailTask>(new NonRequestScopedParameter());
}
}
В Web.Config
<ScheduleTasks>
<Thread seconds="60">
<task name="ExecuteEmailTask" type="namespace.ExecuteEmailTask, AssemblyName" enabled="true" stopOnError="false" maxTries="5"/>
</Thread>
</ScheduleTasks>
В Global.asax
protected void Application_Start()
{
/* intialize Task */
TaskConfig.Init();
TaskManager.Instance.Initialize(TaskConfig.ScheduleTasks);
TaskManager.Instance.Start();
}
Синтаксис Ninject Bind
kernel.Bind<DbContext>().ToSelf().InRequestScope(); // Default bind
kernel.Bind<DbContext>().ToSelf()
.When(x => x.Parameters.OfType<NonRequestScopedParameter>().Any())
.InCallScope(); // For Scheduler
Замечания: EmailTask
класс также естьSomeReposity
как аргумент конструктора.
Запросы: -
Но что такое синтаксис привязки для разрешенияTaskScheduler(IResolutionRoot resolutionRoot)
?Какой код конфигурации для запускаTaskScheduler
?Как сказать поставитьIFakeDbContext
непосредственно в конструктор, может ли это работать сIUnitOfWork<FakeDbContext>
?проблема
Задача не может вызвать с помощью перегруженного конструктора, она может вызывать толькоTaskScheduler
Конструктор по умолчанию.
Вопрос 4: Можно любым способом вызватьTaskScheduler(IResolutionRoot resolutionRoot)
отTaskScheduler
конструктор по умолчанию?
Пример фрагмента кода для создания задачи и запуска с использованиемSystem.Threading.Timer
private ITask createTask()
{
if (this.Enabled && (this._task == null))
{
if (this._taskType != null)
{
this._task = Activator.CreateInstance(this._taskType) as ITask;
}
this._enabled = this._task != null;
}
return this._task;
}
Вопрос 5: Могу ли я решитьTaskScheduler(IResolutionRoot resolutionRoot)
Вот ?
решаемая
public ExecuteEmailTask() : this(DependencyResolver.Current.GetService<IResolutionRoot>())
ИЛИ ЖЕ
public ExecuteEmailTask() : this(new Bootstrapper().Kernel) { }
public ExecuteEmailTask(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}