我对在WinForms应用程序中使用依赖注入来管理DbContext
生命周期的正确方法感到困惑。现在,我的代码看起来像下面的
static class Program
{
// This is the main window's controller, which stores all the
// dependencies that are resolved in the composition root and handles
// passing those dependencies to other objects
private static IMainController mainController;
private static void ComposeDependencies
{
UnityContainer container = new UnityContainer();
container.RegisterType<IMyContext, MyContext>();
container.RegisterType<IOrderRepository, OrderRepository>();
container.RegisterType<IOrderService, OrderService>();
mainController = new MainController(
container.Resolve<IOrderService>());
}
}
public class OrderRepository : IOrderRepository
{
private readonly IMyContext context;
public OrderRepository(IMyContext context)
{
this.context = context;
}
}
public class OrderService : IOrderService
{
private readonly IOrderRepository repository;
public OrderService(IOrderRepository repository)
{
this.repository = repository;
}
}
public class MainController
{
private readonly IOrderService orderService;
public MainController(IOrderService orderService)
{
this.orderService = orderService;
}
public void DoSomethingWithAnOrder()
{
FirstTypeOfController controller = new FirstTypeOfController(this.orderService);
// Show window, assign controller, etc.
}
public void DoSomethingElseWithAnOrder()
{
SecondTypeOfController controller = new SecondTypeOfController(this.orderService);
// Show window, assign controller, etc.
}
}
我遇到的问题是,这个模式会导致我的程序启动时创建所有存储库,因此MyContext
实例会在整个程序中保持不变。因此,当数据库在我的程序之外更新时,我的程序看不到新数据,因为MyContext
正在使用对已经加载的数据的引用。
如果这是一个Web应用程序,那么我会对每个请求都有新的依赖关系,但由于这是WinForms,我不明白如何解决这个问题,同时保留一个组合根并且不传递我的Unity我的程序周围的容器(或有一个静态引用),以便每个控制器可以解析自己的每个实例依赖项。
这个问题的标准解决方案是什么,是否存在我正在编写依赖项或使用DbContext
的方式/位置错误的内容?
我知道MVC对于Web应用程序来说意味着更多,而像MVVM或MVP这样的东西可能更适合非web,但是那些只会被调用一次的单一组合根也存在同样的问题。
答案 0 :(得分:0)
这取决于您如何配置依赖项注入,如果它的Singleton或每个范围一个实例。我知道在Ninject的DI框架中你可以使用:
指定//Thread Scope (New instance on each injection)
kernel.Bind<IInterface>.To<ConcreteClass>().InThreadScope();
//Singleton Scope (One instance per application)
kernel.Bind<IInterface>.To<ConcreteClass>().InSingletonScope()
答案 1 :(得分:0)
我没有看到你的实现有什么问题,看起来是正确的。这是正确的,您在程序启动时初始化您的存储库,这很好,并且您可以保留整个应用程序生命周期的上下文。使用存储库,您可以调用一个对数据库执行某些操作的方法;在获取数据的情况下,如果正确实现,您将始终获得最新数据,除非您在应用程序加载时检索它并将其存储在某处以供将来访问(例如全局变量,设置等)。 p>