问题描述
我正在尝试通过遵循MVVM模式并使用控制反转来开发WPF应用程序。 我正在使用简单注入器作为IoC容器。
我必须为DbContext
实现类似于Ambient Scope的东西。基本上,每次我需要调用与数据交互的服务方法时,都会释放它的新UoW实例,并且该实例将在所有实例中使用。实现数据库操作的数据服务。
像这样的东西:
// Example of Service method
[STAThread]
static void Main()
{
_container = Bootstrap();
Debug.WriteLine(CultureInfo.CurrentCulture);
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-Us");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
_app = new App();
_app.InitializeComponent();
var mainWindow = _container.GetInstance<MainWindow>();
mainWindow.Closed += MainWindow_Closed;
_app.Run(mainWindow);
}
public partial class MainWindow : Window
{
public MainWindow(MainWindowviewmodel viewmodel)
{
InitializeComponent();
DataContext = viewmodel;
}
}
<Window x:Class="WpfRaddispenser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:userControls="clr-namespace:WpfRaddispenser.UserControls"
xmlns:vm="clr-namespace:WpfRaddispenser.viewmodel"
mc:Ignorable="d"
Title="WpfRaddispenser" Height="768" Width="1024"
d:DataContext="{d:DesignInstance vm:MainWindowviewmodel}">
<Grid>
<Grid.RowDeFinitions>
<RowDeFinition Height="Auto"/>
<RowDeFinition Height="*"/>
<RowDeFinition Height="*"/>
</Grid.RowDeFinitions>
<userControls:NavigationBar Grid.Row="0" DataContext="{Binding Navigator}"/>
<ContentControl Grid.Row="1" Content="{Binding Navigator.Currentviewmodel}"/>
<ContentControl Grid.Row="2" Content="{Binding Navigator.Headerviewmodel}"/>
</Grid>
</Window>
public class Navigator : ObservableObject,INavigator
{
private readonly IviewmodelAbstractFactory _abstractFactory;
private viewmodelBase _currentviewmodel;
private viewmodelBase _headerviewmodel;
public Navigator(IviewmodelAbstractFactory abstractFactory)
{
_abstractFactory = abstractFactory;
}
public viewmodelBase Currentviewmodel
{
get
{
return _currentviewmodel;
}
set
{
_currentviewmodel = value;
OnPropertyChanged();
}
}
public viewmodelBase Headerviewmodel
{
get
{
return _headerviewmodel;
}
set
{
_headerviewmodel = value;
OnPropertyChanged();
}
}
public ICommand UpdateCurrentviewmodelCommand => new UpdateCurrentviewmodelCommand(this,_abstractFactory);
public ICommand UpdateHeaderviewmodelCommand => new UpdateHeaderviewmodelCommand(this,_abstractFactory);
}
public class UpdateHeaderviewmodelCommand : ICommand
{
private INavigator _navigator;
private readonly IviewmodelAbstractFactory _viewmodelAbstractFactory;
public UpdateHeaderviewmodelCommand(INavigator navigator,IviewmodelAbstractFactory viewmodelAbstractFactory)
{
_navigator = navigator;
_viewmodelAbstractFactory = viewmodelAbstractFactory;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
if (parameter is MenuViewType viewType)
{
_navigator.Headerviewmodel = _viewmodelAbstractFactory.Createviewmodel(viewType);
}
}
public event EventHandler CanExecuteChanged;
}
public class HeaderviewmodelFactory : IWpfRaddispenserviewmodelFactory<Headerviewmodel>
{
private readonly ProductionService _service;
public HeaderviewmodelFactory(ProductionService service)
{
_service = service;
}
public Headerviewmodel Createviewmodel()
{
return new Headerviewmodel(_service);
}
}
public class Headerviewmodel : viewmodelBase
{
private readonly ProductionService _service;
public Headerviewmodel(ProductionService service)
{
_service = service;
CreateData();
}
private void CreateData()
{
_service.CreateTestCycle();
}
}
public class CycleService : GenericDataService<Cycle>
{
private readonly IUnitOfWork<WpfRaddispenserDbContext> _uowContext;
public CycleService(IUnitOfWork<WpfRaddispenserDbContext> uowContext)
: base(uowContext)
{
_uowContext = uowContext;
}
public void CreateTestCycle()
{
var cycleDataService = new GenericDataService<Cycle>(_uowContext);
var vialDataService = new GenericDataService<Vial>(_uowContext);
Cycle c = new Cycle();
c.BatchName = "test";
Vial v = new Vial();
v.Name = "Test Vial";
c.Vials.Add(v);
_uowContext.CreateTransaction(IsolationLevel.ReadCommitted);
try
{
vialDataService.Create(v);
_uowContext.Persist();
var list = vialDataService.GetAll();
cycleDataService.Create(c);
_uowContext.Persist();
_uowContext.Commit();
}
catch (Exception e)
{
Console.WriteLine(e);
_uowContext.RollBack();
throw;
}
finally
{
_uowContext.dispose();
}
}
}
我已经以这种方式实现了该服务,因为到目前为止,我不知道该服务的需求,因此我希望有可能在业务逻辑上控制交易,并且有可能混合任何实体以用于任何数据服务。
但是通过在容器上使用这种注册方式
private static Container Bootstrap()
{
// Create the container as usual.
var container = new Container();
// Register your types:
// Register your windows and view models:
container.Register<WpfRaddispenserDbContextFactory>(Lifestyle.Transient);
container.Register<IUnitOfWork<WpfRaddispenserDbContext>,WpfRaddispenserUOW>();
container.Register(typeof(CycleService));
container.Register<IWpfRaddispenserviewmodelFactory<Productionviewmodel>,ProductionviewmodelFactory>(Lifestyle.Transient);
container.Register<IWpfRaddispenserviewmodelFactory<Anagraphicviewmodel>,AnagraphicsviewmodelFactory>(Lifestyle.Transient);
container.Register<IWpfRaddispenserviewmodelFactory<Headerviewmodel>,HeaderviewmodelFactory>(Lifestyle.Transient);
container.Register<IviewmodelAbstractFactory,viewmodelAbstractFactory>(Lifestyle.Transient);
container.Register<INavigator,Navigator>(Lifestyle.Transient);
container.Register<MainWindowviewmodel>();
container.Register<MainWindow>();
//container.Options.EnableAutoVerification = false;
//container.Verify();
return container;
}
我不明白为什么第二次收到CycleService
时会收到这种异常:
System.ObjectdisposedException:'无法访问已处置的对象。导致此错误的常见原因是,处理从依赖项注入中解析出来的上下文,然后稍后尝试在应用程序中的其他位置使用相同的上下文实例。如果在上下文上调用dispose()或将上下文包装在using语句中,则可能会发生这种情况。如果使用的是依赖项注入,则应让依赖项注入容器负责处理上下文实例。对象名称:“ WpfRaddispenserDbContext”。
我了解到,在所有实例都注册为临时实例之后,每次新建一个实例时,所需的所有实例都是新的还是还有更多?
编辑:我已经通过添加所有调用cycleService的部分进行了修改。
基本上我想要的是当用户执行导航命令时(名称UpdateHeaderviewmodel暂时不重要...这只是一个示例) 每次使用新实例创建新的viewmodel以及其自身的视图以及所有必需的服务。
public interface IUnitOfWorkFactory<TContext> where TContext : DbContext
{
IUnitOfWork<TContext> CreateUnitOfWork();
}
public class WpfRaddispenserUOWFactory:IUnitOfWorkFactory<WpfRaddispenserDbContext>
{
private readonly WpfRaddispenserDbContextFactory _factory;
public WpfRaddispenserUOWFactory(WpfRaddispenserDbContextFactory _factory)
{
this._factory = _factory;
}
public IUnitOfWork<WpfRaddispenserDbContext> CreateUnitOfWork()
{
return new WpfRaddispenserUOW(_factory);
}
}
此注册
private static Container Bootstrap()
{
// Create the container as usual.
var container = new Container();
// Register your types:
// Register your windows and view models:
container.Register<WpfRaddispenserDbContextFactory>(Lifestyle.Transient);
container.Register<IUnitOfWork<WpfRaddispenserDbContext>,WpfRaddispenserUOW>();
container.Register<IUnitOfWorkFactory<WpfRaddispenserDbContext>,WpfRaddispenserUOWFactory>();
container.Register(typeof(ProductionService));
container.Register<IWpfRaddispenserviewmodelFactory<Productionviewmodel>,Navigator>(Lifestyle.Transient);
container.Register<MainWindowviewmodel>();
container.Register<MainWindow>();
//container.Options.EnableAutoVerification = false;
//container.Verify();
return container;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)