Pergunta

When implementing a Onion architecture in ASP.NET MVC, it is my understanding that we should/could expose the IDataContext interface, which can be injected and referred to in the UI.

So basically in ASP.NET MVC, we could do:

_context.Products.Add(myBadProduct);

Doesn't that allow the UI layer to implement business logic? I believe that one of the basic philosophies of Onion is that it provides clear understanding what code goes into what layer and explicitly forbids the UI layer from implementing business logic.

If we are exposing the storage to the UI (with, or without SaveChanges capability), we let the UI developers implement custom business logic.

This can be 'fixed', by exposing all operations to the underlying IDataContext, via a Domain Service such as this only.

To summarize my question into one sentence:

Should we allow the UI layer to touch the IDataContext or should we expose all our context operations only via a Domain Service? If we expose the IDataContext, is it also ok to expose SaveChanges method, defined in IDataContext (and implemented for example in the actual EfDataContext)?

I think the IDataContext should be exposed as readonly (i.e. without SaveChanges capability), for querying purposes, while the C_UD methods should be exposed as Domain Services. Right or wrong?

Foi útil?

Solução

First of all, I’d like to remind that even if onionarch.codeplex is a very very good starting point for everyone that wants to get into Onion architecture (everything is pretty straightforward), mentioning it as a source for thinking is ok, but the intention of Matt Hidinger was surely not to provide with any production code here.

That said, IMHO the decision depends on several parameters.

Do you work alone or in a large team? Are all the developers involved, pretty good ones? Do you have DBAs? Do you care about performances?

I’m working in a company with a lot of different developers. Our sites are hit tons of time a minute, our web applications are accessing a pretty huge DB which is closely monitored by a strong DBA team. If I let developers create their own queries towards the DB, I’m not sure that everyone will activate a profiler to see if the generated T-SQL is ok or not. It would be impossible to control every single Linq2Entities query. This would lead to performance issues and DBA’s heart attacks :-) (Of course caching would help out, but it doesn’t solve everything).

So, as @DarinDimitrov said, both approaches are correct, but from my side I prefer not letting consumer plays directly with IDataContext.

Outras dicas

Should we allow the UI layer to touch the IDataContext or should we expose all our context operations only via a Domain Service?

Actually the 2 approaches are correct. You will see that there are people recommending the one and other people recommending the second. For example Ayende Rahien wrote a nice blog post in which he explains that he prefers simply exposing the underlying interface to the consumer instead of ending up with a service layer with methods like:

  • FindCustomer(id)
  • FindCustomerWithAddresses(id)
  • FindCustomerWith..
  • ...

Personally I also tend to do that but once again this is subjective. As far as the SaveChanges method is concerned, I would also expose it to the consumer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top