MVC + WCF: Architecture Design Decisions - c#

I'm currently working on a project that consists of an ASP.NET MVC web application with a back-end wrapped in WCF services. I've used MVC and WCF on past projects but I've never been responsible for designing the architecture from scratch. I'm hoping for some feedback on my current design to make sure that I'm employing good design practices from a high level architectural view.
Here is the dependency diagram to give an idea of how things are structured:
A few things to note:
Common MyApp.Utilities project is for any functionality which needs to be shared across layers. Currently it only contains extension methods.
Service contracts and data contracts are in a common project which is shared between both layers.
EntityFramework is being used for data access.
Mapping goes Entity <=> DTO (data contract) <=> ViewModel
Still working on this, using AutoMapper and not entirely sure as to how I should "rehydrate" the DTOs when they are passed back from the presentation layer.
ServiceImplementation is simply a wrapper for business logic which is contained in a separate assembly.
The presentation and service layers are to be deployed to separate physical servers
Packages are all contained in a single folder in the solution's root folder and are checked into version control
Does any of this stand out as bad practice?

• Service contracts and data contracts are in a common project which is shared between both layers.
I would avoid this. It may seem like extra work but I would break these out into separate namespaces and classes, even if it leads to duplication. I normally shy away from planning for the unforeseen, however, I have never had a project in which all my data contracts aligned with all my service contracts. The hacks to accommodate the differences tend to lead to confusing anti-patterns.
The majority of these classes will have identical properties and they can easily be mapped using an auto mapper.

The architecture that you proposed above is pretty similar that I've used in my projects.
Some comments:
Data contracts (Entity Framework) are not in a common project;
We are using currently AutoMapper to map between entity framework model and service model (simple and complex types) and between
service model and view model.
We have interfaces implementation in DAC, Service layer and Presentation layers, to use dependency injection (we use Ninject), to
make layers more "testable", so we also have contracts in all these
layers.
Presentation is basically Web Api with restful methods.
It works great and I don't see any issues in your archtecture.

Related

Patterns of Enterprise Application Architecture - consolidating business data

To give you a quick overview of my application architecture, I have the following layers in my application:
Domain Model - Models the problem domain and business rules.
Service Model - Models the service contract consumed by the application.
Data Access Layer - Persistence of domain models, in this case using EF.
Services - Implementations of the service model.
Website - MVC web application.
Web API - RESTful web service API.
Now the problem is that the Web API came later; the MVC web application was the first thing that was built on top of the architecture.
I find myself having to replicate business logic and ViewModels (MVC) and Messages (Web API)...According to the DRY principle, I shouldn't be doing this, so the natural solution is to push the business logic into its own layer which is independent of the application layers.
But...this means that the business logic layer needs it's own set of models which sit between the application layer and the business logic layer. In this respect, it would not be applicable to use domain models, since these really shouldn't ever hit the application layer.
So in short, I'm looking for an industry accepted standard for business logic modelling. Is there an accepted standard for how this should work, and if so, what type of model (i.e. it's not a domain model, and it's not a view model) belongs to the business logic layer?
You have stumbled upon a contested point of discussion. I myself have struggled with this for a long time.
Object bigots will argue that you shouldn't even have a service layer. Your domain model could then be directly consumed which would eliminate the duplication of logic. Granted, those were the good old days of software modeling. With the advent of the web, apis and SOAs, we are forced to look at alternative ways of modeling our software. Enter Anemic Domain models.
Anemic Domain models essentially consist of light weight objects that resemble DTOs more than anything, with underlying services that do the heavy lifting.
The architecture you have described above seems to be a hybrid design. I am guessing by now you must have run into the issue of mapping EF classes to domain objects, which creates yet another layer of objects, unless you use POCOs, in which case you run into namespace issues and what not.
Anyways, I don't think there is an industry standard. What I can tell you is that I have seen a few patterns emerge here and there leaning towards Anemic Domain Models and it's not hard to see why. In disconnected environments (e.g. web, API), complex objects don't work very well, hence the affluence of services.
Since you have layered your application nicely and do not wish to expose your domain model objects, I would suggest using Anemic Models in your service implementations. These would essentially function as DTO objects that can be reused and serialized if the need be, but can also implement basic logic that may even map back to functionality implemented in the services.
On a final note, there is no one-size-fits-all. Use the right tool for the job. Patterns are meant to be guidelines, not step-by-step instructions, so make sure you feel free to tweak them in order to fit your particular needs while retaining the general idea.
You can read more about Anemic Domain Models here:
https://en.wikipedia.org/wiki/Anemic_domain_model
Make sure to check out Martin Fowler's objections to Anemic Domain Models as well:
http://www.martinfowler.com/bliki/AnemicDomainModel.html

Do I need WCF layer in the backend layer of my WPF application?

I am creating my first stand alone desktop WPF application using Entity Framework. Do I need a WCF layer to access database? Is this a bad practise if I just call DBContext directly from ViewModels?
TL; DR
The short answer is: it depends!
The long answer
It depends on your use case you need to implement. If you need to add another layer of abstraction -the WCF layer- to hide your OR/M away you can do it. However if your strategy is easy enough like a standalone WPF application I wouldn't bother making a WCF layer. You can simply access the IDBContext in your application, but keep in mind to not tightly couple your viewmodels with EF.
Always worth try keeping the concerns separate!
And these concerns are:
Data- or Persistence (EF) Models that are used to map your database to your OO models
ViewModels that are supporting your Views with data to show
Mapping of your Persistence and ViewModels
This way you can achieve a lightweight setup that aims for better separation and better testing ability.
Further Extensibility
Later on your development path, when you arrive at a point where you need to add an infrastructural concern like a WCF layer which could serve as a public API -or an entry point- to your shared database access, you can easily add it as a new project, put its classes behind interfaces (these are the only ones you will have as reference added to your WPF project) and let this project have the exact implementations.

Need Architectural Advice for Large scale .Net MVC Project

I will try to explain in as much detail as possible. There may be similar questions here on SO and I've gone through all of those but none of those have what I needed.
So, I'm starting out with a large scale C# MVC5 based Web Project and I want to organize everything in as much decoupled way as possible. For the database part I'm going to use Data Access ORM from Telerik (Previously known as Open Access) because I will be using MySQL for my project.
So far I have organized everything as below. I have defined solution level folders to divide the projects because I think there may be a possibility to have more projects in one layer in future.
**Solution**: td
- Business (Folder)
-- td.core (Project) (Contains Services and ViewModels)
-- td.interfaces (Project)
- Data (Folder)
-- td.data (Project) (Contains Database Models i.e. Telerik, Repository, Context Factory and Unit of Work class)
- Presentation (Folder)
-- td.ui (Project) (MVC5 Project, also Implemented IoC here)
- Shared (Folder)
-- td.common (Project)
Generally, when you bind models in your MVC project, if you have just one project in your solution, it works pretty easily without an issue.
i.e. in a MVC Controller
var obj = new TempClass();
return View(obj.getAllUsers());
and then in the corresponding view you use this at the top
#model (model type here)
When I separate all these layers in their own projects as mentioned above. The data layer would be the one directly communicating with the database hence I will generate the Telerik Data Access rlinq schema in my Data node where it will also generate the classes for the tables in my database (Default config)
Now, from the setup above, from the controller I'm supposed to call the Business layer to fetch the data and which will communicate with the Data node.
The question is that in the controller and in the view I will need the data types / references of the model I'm binding to. So, should I keep my automatically generated classes still in the Data node or can I move ONLY the generated classes to the Shared Node and then use those for the binding in the Controller/View? Which one is going to be a good practice? as I don't want to reference the Data nodes directly in the controller otherwise there is no point in separating everything like above.
Another quick question. I would be integrating so many third party APIs via REST/SOAP. In which layer should these best fit?
If anyone has any other Architectural suggestion or something that I'm missing here, please do suggest.
Thanks in advance everyone.
UPDATE!!!
Please see my updated architecture above.
Here's what I did so far.
I have added Repositories, Services and IoC.
In my Global.asax, I'm initializing the IoC which configures the Services etc for me.
My controller has an overloaded constructor now having the service from the business layer as the parameter.
Controller calls the service to get the data and the service calls the repository for it.
I have followed the generic repository path instead of creating repositories manually for each type
For 3rd party APIs, I will use the data layer and business later won't know where the data came from. It just needs to ask what it needs.
All this was made easier with the help of a dedicated Interfaces project which is being referenced from both the Business and Data layers when needed. Because as both want to implement abc interface I cannot declare it in either Business or Data layer since there would be circular referencing then which prevents me to reference both (Business/Data) projects to each other.
So, with the help of above changes, I can easily do what I want now and Everything is working perfectly as I want. Now the last question I have is
Is there any flaw in this architecture?
For a domain-centric architecture where it's easy to add another type of UI or change persistence technology and where business classes are easily testable in isolation, here's what I'd do :
Business layer with no dependencies. Defines business types and operations.
Data layer with data access objects/repositories that map from database to business types. You can also put your third party API accessors and adapters here. Depends on Business layer where repository interfaces are declared.
No Shared layer. Business types are the basic "currency" that flows through your system.
UI layer depending on the data access interfaces declared in the Business, but not on the Data layer. To decouple UI further, you can introduce an additional UI-agnostic Application layer.
You can read more about this at Onion Architecture or Hexagonal Architecture.
As it is, your architecture is pretty much data-driven (or Telerik Data driven) since the business and UI layers are tightly coupled to the Telerik schema. There's nothing wrong with that, but as I said in my comment, it enables other things such as quick development from an existing database schema, over full domain decoupling, framework agnosticism and testability.
Whether your Telerik generated model lives in the Data or Shared module makes little difference in that scenario IMO. It is still the reference model throughout your application and your controllers will be coupled to it anyway. The only thing I would advise against is moving the generated files manually - if it can be automated all the way, definitely do it or don't move the files at all.
I'm nether an expert for your special technologies, nor would I regard this as the ultimate answer, but I give you some hint's of the possibilities you may have (depending on your technologies):
Business should have exclusive access to data
Currently I don't really get, why your controller and view need access to any data-base related stuff at all? Shouldn't your business layer handle all of that and hide it from controller and view? But let's assume it's necessary for some reason.
Ways to split the data layer
You shouldn't move generated classes manually. You could change your generation-settings, to generate them elsewhere partially. But manually cherry-picking and moving them, results in an architecture which is hard to maintain.
The cleaner solution would be, if you can change the visibility of your classes. Can you generate classes with project or folder visibility instead? Or can you only export defined packages or classes in the project settings?
A workaround which requires more maintenance is the local extension. You could create new classes in your shared folder, which derive from the data layer classes.
Stucturing external APIs
Give them one or more own projects, so they are easier to change later. I know approaches where you have one main folder for each API. This makes each of them easy to change, but clutters your workspace. The important project will only be 4 out of 1000 projects. I normally prefer one folder containing all APIs. Thus the APIs are slightly harder to change, but your workspace stays clean. Your decision depends on two facts: how often do you change, add, remove or just study the APIs. And does your IDE provide a way to "hide" folders/projects from your workspace.
Hope this helps a little :)

Decision in regard to adding a new project independent of the application's layers

Hi I m in the process of refactoring an application for witch I was tasked to restructure the app because of the bad coding and architectural design. Fortunately it is not that much work to be done because the project was started a few months ago.
After some discussions with my colleagues I have decided to separate the application into three Layers (DataAcces , Business Logic and GUI).
I have restructured the entire solution putting into the mix Entity Framework , Automapper and Unity.
After I had a discussion with my Project Manager I learned that at some point it may be required to replace Entity Framework and Unity with NHibernate and Ninject , because of the client's team knowledge with these frameworks.
It will take some time before this decision is taken and it may be possible that someone else will have to do this.
I have decided to create wrappers around around Entity Framework , Automapper and Unity and place them in a separate project , if at some point in the application lifetime the decision will be taken to change them.
As it stands I am not sure to witch layer in my application will this project belong because it contains code that is needed by all layers.For example:
-Entity Framework - DatAccess
-Automapper - Service Layer
-Unity - GUI Layer, Service Layer , DataAcces Layer
Because of this a reference will exist to this project in all layers of my application.
I am not sure if this will be good for the overall architecture of the application.
What I know so far regarding N-tier architectures is that you have to have clear separations between your layers.
Is there a better option for this that I am missing , or it is correct to proceed this way?
You should add a DataContracts project.
So the references will be like this:
DataAcces Layer
Entity Framework - note: this should not be exposed for public, the DAL should wrap it
DataContracts
Automapper
DataContracts
GUI Layer
DataContracts
Service Layer
DataContracts
Unity
DataAcces Layer
Automapper
DataContracts
GUI Layer
Service Layer
Your layers should have interfaces that are defined in the DataContracts project. For example, in your Service Layer you won't depend on a DataAccesController, you'll depend on an IDataAccesController. You can use the unity layer to wire everything together, since that's what unity is for.
Having an interchangeable IoC framework is not really recommended.
If the client decides they rather have nhibernate instead of entity framework, they'd only have to modify the DAL
of course I have no idea about your current implementation, but this is how I'd generally set it up.

Placement of DTO / POCO in a three tier project

I've been in the process of re-writing the back-end for a web site and have been moving it towards a three-tiered architecture.
My intention is to structure it so:
Web site <--> WCF Service (1) <--> Business Layer (2) <--> Data Layer (3)
My issue is with the placement of the DTO's within this structure. I'll need to use DTO's to move data between the business layer and the WCF service and from the WCF service to the consuming web site.
During my research on here I've read some excellent discussions though I've been left scratching my head a bit:
Davide Piras makes some great points in this post and if I were to follow this design then I'd declare interfaces for the POCOs in a separate project. These would then be implemented by tiers (1) and (2). Whilst I like the use of interfaces it does seem like I'd be making more work for myself by declaring POCOs in (1) and (2) and then copying their data back and forth using something like AutoMapper.
This post uses a system where a business objects project is created which would be referenced by all tiers. This seems to be simplier than the other solution and seems to lead me to a solution that would be
Web site <--> WCF Service (1) <--> Business Layer (2) <--> Data Layer (3)
^ ^ ^
| | |
[ -- Business Objects Referenced here --]
My question is this: is there a code smell from sharing the business objects across three layers of the solution or are the two methods I've listed above just two different ways of cracking the same nut?
Let's think of your UI (website) and service (WCF + BL + DAL) as two distinct entities.
If you have 100% control over both, you should choose approach #2 since it will avoid translation between WCF proxy objects and your business objects in the UI layer.
Else, you are better off with approach #1 since one of the entities is kind of a 'black box' and is subject to change by external stakeholders. So, it's safer to maintain an internal set of business objects. This will need translation between your business objects and the WCF proxy objects (through Extension methods or a translator framework).
Now, not exactly sure of your UI layer complexity or its implementation (MVC, WebForms, etc.), so you may or may not need View specific objects (lighter for data-binding, faster to serialize to JSON, etc.), let's call this object as the Model.
If you don't need a distinct UI specific Model, suggest to mark your business objects as DataContract (in the context of WCF) and use them across layers. Don't forget to explicitly mark entities as Serializable if you are invoking WCF via the web ($.ajax).
Else, use DataContract in the service and a translator to convert DataContract to Model in the UI layer. A Service Adapter is a good fit here - it sits in the UI layer and is responsible for consuming the WCF service and translating between DataContract and Model. You may use a Service Proxy in the UI layer, which is a wrapper over your WCF service and is consumable over the web.
Lastly, aren't you are missing a reference to the Business Objects in your Data Layer? I believe you will populate your Business Objects from the data-store in the Data Layer itself.
I would say that it often depends on the complexity of the project you're building. For smaller projects that I've built, I shared my 'entities' (they were just simple DTOs, serializable data buckets with getters and setters) across the layers and didn't care too much about this. On of the biggest downsides was that the logic got scattered across the project (not only in the 'Business Layer') and had a procedural-style all around. This really seems like the Anemic Domain Model, but the complexity didn't creep in as the project didn't grow too much. Entity Framework has some templates you can build you entities off of as such (if I'm not mistaken they're called self tracking entities?).
For medium/bigger projects, I wouldn't use this approach and would keep entities and DTOs separately as they would serve different roles. The DTOs might have a totally different shape than your entities and trying to share them between the tiers/layers would be often smelly.

Categories