C# 我们可以在 ViewModel 中用具体类型实例化接口吗

C# Can we instantiate Interface with concrete type in ViewModel

我正在尝试在 WPF 应用程序中实施 MVVM 模式。我已经使用依赖注入在我的视图模型的构造函数中获取类型,就像这样。

private IEntity _newEntity;
private readonly IEntityService _entityService;

public MainViewModel(IEntity entity, IEntityService entityService)
{
    _newEntity = entity;
    _entityService = entityService;
}  

现在我可以出于任何原因这样做 _newEntity = new Entity(); 还是反模式?换句话说 ViewModel 可以与具体类型耦合吗?

这取决于您要存档的内容。

如果你想在 MainViewModels 的构造函数中像这样调用 _newEntity = new Entity();

public MainViewModel(IEntityService entityService)
{
    _newEntity = new Entity();
    _entityService = entityService;
}  

然后您将在构造函数中创建 class Entity 的新对象,不再需要通过依赖注入作为参数传递给构造函数。但是现在每个 MainViewModel 都会有一个不同的 Entity 实例,而且可能更重要的是,您不会有一种干净的方式从其他 ViewModel 或服务访问 Entity。如果这是你想要的,那很好。

如果您希望其他 ViewModel 或服务使用相同的 Entity 实例,您可以在 DI(依赖注入)容器中注册一个 Entity 实例。大多数 DI-containers 都为该用例提供功能,例如containerRegistry.RegisterSingleton<IEntity>();Prism.

除了这个…… 如果你没有看到任何未来需要使用 classes 除了 Entity 实现 IEntity 那么(在我看来)也没有无缘无故地使代码通用的原因。这遵循 YAGNI (You aren't gonna need it) 原则,比如不要实现您可能不需要的抽象。在这种情况下,您可以将 Entity 注册为具体类型而不是像这样的接口 containerRegistry.RegisterSingleton<Entity>(); 并将您的 MainViewModel 更改为

private Entity _newEntity;
private readonly IEntityService _entityService;

public MainViewModel(Entity entity, IEntityService entityService)
{
    _newEntity = entity;
    _entityService = entityService;
} 

还有一个很好的 video by SingletonSean 他没有使用接口,而是使用具体的 classes 作为他的 ViewModels 的构造函数参数。

请注意,我最近才开始接触 WPF,因此在撰写此答案时我并没有声称自己是专家。

如果视图模型负责创建实体,那么通过 new Entity() 创建实体就完全没问题了。

另一种选择是将视图模型注入代表视图模型创建实体的工厂。