Я использую Ninject, но это должно относиться к любому IoC.
У меня есть синглтон с фоновым потоком, который работает в течение всего срока службы программы. Каждые 5 минут фоновый поток запускает пара рабочих. Эти рабочие вводятся с использованием автофака
Func<IEnumerable<IWorker>>
Но это решает только некоторые проблемы, позвольте мне объяснить, что некоторые из моих работников имеют зависимость от репозиториев, и каждый репозиторий имеет зависимость от контекста среды Entity, имеющей область видимости потока (Он будет удален после завершения потока ). Это означает, что когда выполняется автофак, и я получаю список работников, их область действия будет находиться в фоновом потоке, который имеет то же время жизни, что и программа, не очень хорошо иметь контекст EF, который живет для всего приложения. Каждый рабочий метод Execute выполняется в отдельном потоке, но это не имеет значения, поскольку Ninject все равно будет прослушивать только основной фоновый поток, который никогда не закончится.
Я решил это очень уродливо, если вы спросите меня, я ввожу не универсальную фабрику
Func<Type, object>
Затем я прошу сборку вернуть все конкретные типы интерфейса IWorker, а затем использую фабричный метод для их вызова в каждом рабочем потоке (что означает, что область действия будет только для рабочего потока, а не для фонового потока), это работает, но это уродливо, и я не могу заглушить IWorkers, что означает, что я больше не могу запускать свои юнит-тесты.
Ребята, у вас есть хорошее решение для меня? : D Спасибо
edit: Спасибо за помощь, Remo, именованная часть области теперь работает, но оригинальная проблема все еще существует. Это мой тестовый код
WorkManager
internal class WorkflowManager : IWorkflowManager
{
private readonly Func<IWorker> testWorker;
private BackgroundWorker backgroundWorker;
public WorkflowManager(Func<IWorker> testWorker)
{
this.testWorker = testWorker;
}
public void Start()
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += DoBackgroundWork;
backgroundWorker.RunWorkerAsync();
}
public void Stop()
{
}
private void DoBackgroundWork(object sender, DoWorkEventArgs e)
{
var test = testWorker();
}
}
Его переплет
kernel.Bind<IWorkflowManager>().To<WorkflowManager>().InSingletonScope();
Рабочий
internal class TestWorker : IWorker, IDisposable
{
public TestWorker()
{
System.Diagnostics.Debug.WriteLine("Contructed!");
}
~TestWorker()
{
System.Diagnostics.Debug.WriteLine("Deconstructed!");
}
public void Dispose()
{
System.Diagnostics.Debug.WriteLine("Disposed!");
}
}
Привязка
kernel.Bind<IWorker>().To<TestWorker>().InCallScope();
Только конструктор вызывается ...: /