【发布时间】:2019-10-29 05:27:43
【问题描述】:
我想使用 Caliburn.Micro 和引导程序重新编写我的第一个小 C# 项目。在我的第一种方法中,我使用了 Autofac,但现在我被卡住了。如果没有 Caliburn,我可以从这样的 db 文件中检索我的员工(注意 scope.resolve 的东西——这就是我现在的问题):
public ObservableCollection<EmployeeEntity> Employees
{
get
{
var container = ContainerConfig.Configure();
using (var scope = container.BeginLifetimeScope())
{
var test = scope.Resolve<IEmployeeRepository>();
_Employees = test.GetAll().ToObservable();
}
return _Employees;
}
set
{
_Employees = value;
}
}
现在我切换到 Caliburn.Micro incl。看起来像这样的引导程序(我想保留 LifeTimeScope 的东西)
protected override void Configure()
{
var builder = new ContainerBuilder();
builder.RegisterType<WindowManager>()
.AsImplementedInterfaces()
.SingleInstance();
builder.RegisterType<EventAggregator>()
.AsImplementedInterfaces()
.SingleInstance();
builder.RegisterType<CalendarViewModel>()
.SingleInstance();
builder.RegisterType<EmployeeViewModel>()
.SingleInstance();
builder.RegisterType<EmployeeRepository>().As<IEmployeeRepository>()
.InstancePerLifetimeScope();
Container = builder.Build();
}
在应用程序启动时,我打开“CalendarViewModel”并获取相应的视图。我的视图包含一个菜单,该菜单通过以下实现在单击时打开第二个视图“EmployeeViewModel”:
private readonly IWindowManager _windowManager;
public CalendarViewModel(IWindowManager WindowManager)
{
_windowManager = WindowManager;
}
public void OpenEmployeeView() => _windowManager.ShowWindow(new EmployeeViewModel());
现在我的问题是如何使用引导程序和使用“Lifetimescope”实现“IEmployeeRepository”将代码从一开始(仅限 Autofac)更改并包含在工作中。
我尝试过的:
我尝试像使用 WindowManager 一样包含“IEmployeeRepository”:
private ObservableCollection<EmployeeEntity> _Employees;
private readonly IEmployeeRepository _emp;
public EmployeeViewModel(IEmployeeRepository Emp)
{
_emp = Emp;
}
public ObservableCollection<EmployeeEntity> Employees
{
get
{
_Employees = _emp.GetAll().ToObservable();
return _Employees;
}
set
{
_Employees = value;
}
}
但是(您可能已经知道)我收到一个错误
CS7036 There is no argument given that corresponds to the required formal parameter
那么如何在 Bootstrapper 中正确实现 Autofac?很确定我的方法不是正确的方法:/
快速总结: (bootstrapper) --application start--> (CalendarViewModel) --menu item--> (EmployeeViewModel)
2019 年 10 月 29 日更新: 线
public EmployeeViewModel(IEmployeeRepository Emp)
{
_emp = Emp;
}
引发错误。我猜是因为我的 OpenCommand
public void OpenEmployeeView() => _windowManager.ShowWindow(new EmployeeViewModel());
不会将任何 IEmployeeRepository 传递给我的 EmployeeViewModel。
2019 年 10 月 29 日第 2 期更新: 新的错误信息
System.InvalidOperationException: "一个无参数的默认构造函数 或一个匹配的签名(System.Int64 Id,System.String FirstName) Calendar.Database.Entities.EmployeeEntity 需要 物化”
被扔在里面 SqlRepository.cs(GetAll返回行抛出错误)
protected SqlRepository(IDbContext dbContext)
{
DbContext = dbContext;
}
public IList<TEntity> GetAll()
{
return DbContext.Connection.GetAll<TEntity>().ToList();
}
我做了什么: 引导程序.cs
builder.RegisterType<EmployeeViewModel>()
.SingleInstance();
builder.RegisterType<DbContext>().As<IDbContext>()
.InstancePerLifetimeScope();
builder.RegisterType<EmployeeRepository>().As<IEmployeeRepository>()
.InstancePerLifetimeScope();
CalendarViewModel.cs
public void OpenEmployeeView() => _windowManager.ShowWindow(IoC.Get<EmployeeViewModel>());
EmployeeViewModel.cs
private readonly IEmployeeRepository _emp;
public EmployeeViewModel(IEmployeeRepository Emp)
{
_emp = Emp;
}
public ObservableCollection<EmployeeEntity> Employees
{
get
{
_Employees = _emp.GetAll().ToObservable();
return _Employees;
}
set
{
_Employees = value;
}
}
(我可以发布一个指向我的 Visual Studio 项目的链接……但不知道这里是否允许)
【问题讨论】:
-
哪一行导致错误?你也可以看看sample 并尝试按照他实现一切
-
(更新了我最初的问题)我确实查看了示例并且我的 IWindowManager 正在按预期工作。我的猜测是我必须在“_windowsManager.ShowWindow”命令中传递 IEmployeeRepository 的实例。对我来说,在 CalendarViewModel 中定义 IEmployeeRepository 没有任何意义,将其传递给 open 命令并在新窗口中使用它(我已经在引导程序中定义了它:) .. 所以我真的需要一些帮助来正确实现它,不快也不脏
-
@Pavel 发现了问题……。在我的实体类深处有愚蠢的继承-.-您提出的解决方案有效
-
没关系,我可以取消删除我的答案,你可以投票认为它有帮助
标签: c# mvvm autofac caliburn.micro