Home > Back-end >  C# Can we instantiate Interface with concrete type in ViewModel
C# Can we instantiate Interface with concrete type in ViewModel

Time:05-24

I'm trying to implement MVVM pattern in WPF app. I've used dependency injection to get types inside my viewmodel's constructor like this.

private IEntity _newEntity;
private readonly IEntityService _entityService;

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

Now can I do this for whatever reason _newEntity = new Entity(); or is it anti pattern? In other words can ViewModel be coupled with a concrete type?

CodePudding user response:

It depends on what you want to archive.

If you want to call _newEntity = new Entity(); in MainViewModelss constructor like this

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

then you're creating a new object of class Entity right in the constructor and don't need to pass as an argument to the constructor via dependency injection anymore. But now each MainViewModel will have a different instance of Entity and probably more importantly you wont have a clean way to access the Entity from other ViewModels or Services. If this is what you want to happen, that's fine.

If you want other ViewModels or Services to use the same instance of Entity you would register an instance of Entity with your DI (dependency injection) container. Most DI-containers offer functionality for that use case, e.g. containerRegistry.RegisterSingleton<IEntity>(); in Prism.

With this out of the way... If you don't see any future in which you're going to have a need to use classes apart from Entity which implement IEntity then (in my opinion) there is also no reason to make the code generic for no reason. This follows the YAGNI (You aren't gonna need it) principle, like don't implement abstractions you probably won't need. In this case you could register the Entity as the concrete type instead of the interface like this containerRegistry.RegisterSingleton<Entity>(); and change your MainViewModel to

private Entity _newEntity;
private readonly IEntityService _entityService;

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

There's also a nice video by SingletonSean where he doesn't us Interfaces but concrete classes for the constructor parameters of his ViewModels.

Please note that I just recently got into WPF, so I'm not claiming to be an expert at the time of writing this answer.

CodePudding user response:

If the view model is responsible for creating entities, then creating these by doing new Entity() is perfectly fine.

The other option is to inject the view model with a factory that creates the entities on the behalf of the view model.

  • Related