Thiago M
Thiago M

Reputation: 191

ASP.NET Core and ViewModelFactory

Hello, I'm trying to implement a ViewModelFactory "pattern" and I was wondering what's the best way to achieve it, considering the constraints of the current IoC container.

public class UserCreateViewModelFactory
{
     private readonly DbContext db;

     public UserCreateViewModelFactory(DbContext db){ this.db = db;}

     public void Create(CreateUserViewModel viewModel)
     {
          //Creates the user
     }
}

I have the above class easily injected into my controllers ctor. The head ache will come when I need more ViewModelBuilders, So I want to avoid two things:

  1. Bloat ctor with injections
  2. Bloat container with registrations

I want to be able to inject an IViewModelFactory on my controller and then using it like this:

[HttpGet]
public IActionResult GetUsers(int id)
{
    return View(viewModelFactory.Build<GetUserViewModel>(id));
}

Notice that on calling Build(T) it has to call the correct IViewModelFactory implementation.

I know that StructureMap container support binding the concrete implementations to the corresponding interface but I'm trying to come up with a solution without having to add another dependecy to the project.

Upvotes: 2

Views: 1572

Answers (2)

Thiago M
Thiago M

Reputation: 191

After sometime researching, I finally came up with a good solution for the this problem.

The solution is basically extending the default IoC capabilities through an IServiceCollection.ConnectImplementations() extension method.

During registration I'll search my concrete classes and connect them with its respective interfaces (like other containers). Then I use a Mediator/Proxy that has IServiceCollection injected and knows which concrete class should be building the view model.

The full solution is better explained by this gist I've created.

Upvotes: 0

Fabio
Fabio

Reputation: 32445

I think if you have builders for building viewmodels, then factory is extra layer of abstraction which simply can be dropped off.
Because you know the type of created viewmodel at compile time you can just inject a builder you need to the controller constructor.

If your controller create a lot of viewmodels and you end up with a lot of builders you need to inject - this can be considered as a sign of violation of Single Responsibility Principle. In that case you need to separate logic of controller to different controllers.

So I want to avoid two things:

Bloat ctor with injections

  • Separate class with bloated constructor to another classes with more specific responsibility which takes smaller amount of dependencies.
  • Or wrap dependencies with one or two, three classes based on their relation

Bloat container with registrations

  • This cannot be a problem, because dependency containers is usually designed to register whole "object graph" of your application

Upvotes: 1

Related Questions