I've builded an N-Tier application for CRUD operation with 3rd party libraries.
This is my app design packaging:
List item
Core - with domain models and entities.
DataAccessLayer - with 3rd party libs NHibernate and IOC container Ninject
Ui - Wpf app or Asp.net MVC app
Now i want to separate UI from DAL, exposing my CRUD repositories via WCF Tcp services.
This choice was made for client-server design:
Server: WCF -> DAL with all 3rd party softwares for Database Connection (a lot of driver are very bigs and expensive to install in 100+ clients).
Client: My WPF or SilverLight UI.
I've builded MVC and WebForms APP, a lot of people think that this is a better solution!
But with wpf I have many possibilities to play with graphics and development is faster for me.
All my repositories extending an Interface (for Dependency Injection with Ninject) and i want to add this to my WCF services without create others Interfaces. A lot of my repo's function returning list of NHibernate objects, how to add Attribute "DataMember" to a non WCF project?
But my simple question is, "WHAT IS THE BEST WAY OF DOING THIS,maintaining a good design?"
Thanks for patience!
Ideally you want all of your business logic in the WCF service with the UI as dumb as possible. That way you can create any number of User Interfaces (WPF, Silverlight, MVC, iPhone even) and they are all small and simple with all the common logic in the WCF.
You need to keep things as loosely coupled as possible so following on from that you don't want to pass database things to the front end. Instead you want to send POCOs or DTOs to the front-end that do just enough for the job. Avoid sending a whole database item to the front-end because ideally your front-end should have no knowledge of what database is being used or how it is structured.
As far as your UI is concerned ONLY the WCF contract is important and the DTOs etc. The WCF should be split into several different layers (or tiers), this depends on your approach but you could have facade, business logic, data access layers (do some research into what fits your situation best). You might want to use repository pattern etc, etc, but that will be in the WCF service and the UI will have no knowledge of what is happening in this "Black box".
Ultimately what you want is for all the components to fit together with the least amount of "coupling" where you should be able to swap one component out for another without everything else "depending" on it and breaking.
This is a DEEP subject and I have scratched the surface but hopefully get your thoughts on the right track!
Related
The reason for asking this question is that I've been wondering on how to stitch all these different concepts together. There are many examples and discussions on i.e. DDD, Dependency Injection, CQRS, SOA, MVC but not so many examples on how to put them all together in a flexible way.
My goal:
Develop modules that with little or no modification can stand on their own
Changing or reworking the UI should be as easy as possible (i.e. the UI should do as little as possible, and be "stupid"
Use documented patterns and principles
To make it easier to ask a concrete question, the main arcitecture now looks like this:
The example shows how to add a note to an employee. Employee Management is one bounded context. Employee has several properties, among those an ICollection<Note>.
The bound context is in my understanding the logic place to seperate code. Each BC is a module. Most of the time I find each of them can warrant their own UI if needed (i.e. some modules might be made available for Windows phone).
The Domain holds all business logic.
The infrastructure holds repository implementation, and services to send mail, save files and utilities that does not belong in the domain. I'm thinking of making some of the common service feautures that I have to use in several domains (like send e-mail) as a sort of an API that I could reference to save some code implementing the same things across several BC's.
The query layer holds all Querys except GetById that I need in the repository to fetch an object. The query layer can query other persistence instances, and will probably need to change some for each UI.
The Wcf or Web Api is kind of my Application layer, it might belong in infrastrucure and not on the outside. This service also sets up the dependencies, so all UI need to do is to ask for information and send commands.
The process starts with the blue arrows. Read the model since that has most of the information.
In step 1 the EmployeeDto in this example is just some of employee properties to show the user information about the employee they need to make a note on (like a note about new experience or something like that).
So, the questions are:
Does implementing a layered arcitecture like this really involve so much mapping, or have I missed something?
Is it recommended (or even smart) to use a Wcf service to run the main logic like this (it practically is my Application Service)
Are there alternatives to Wcf without having my domain objects in my UI layer?
Is there anything wrong with this implementation. Any fall pits to look out for?
Do you have any good examples to recommend looking at that can help me to understand how all these concepts are supposed to work together.
Update:
I've read through most of the articles now (quite a bit of reading) except for the paid book (requires a bit more time to do). All of them are very good pointers, and the way of thinking of the Wcf of more as an adapter seems to be a good answer to question 2. JGauffins work on his framework is also very interesting if I'm planning to go the that route.
However, as mentioned in some of the comments beneath I feel some of the examples tends towards recommending or implementing event and/or command sourcing, message buses and so on. To me it is overkill to plan for that level of scaling right now. As many business applications this is a "large" (in terms of an internal application, think max a few thousand) number of users working on a large set of data, not a highly collaborative domain in the sense of needing to implement event and command queues often assosiated with CQRS to cope with that.
Based on the answers below, the approach I'll start with will be based on the model above and the answers like this:
I'll just have to cope with mapping. Thoe pros outweighs the cons.
I'll pull application services back to the infrastructure and
consider Wcf as an "adapter"
I'll use command objects and send to application service. Not
polluting my domain with domain objects.
To keep complexity down I try to manage without event/command
sourcing, message buses etc for now.
In addition I just wanted to link to this blog post by Udi Dahan about CQRS, I think things like this keeps complexity down unless they are really needed.
There is a trade-off between mapping and layers. One reason certain mappings exist is because appropriate abstractions aren't available or feasible. As a result, it is often easier to just explicitly map between layers than trying to implement a framework that infers the mappings, but I digress; this hinges on a philosophical discussion of the issue.
The WCF or WebAPI service should be very thin. Think of it as an adapter in a hexagonal architecture. It should delegate everything to an application service. There is conflation of the term service which causes confusion. Overall, the goal of WCF or WebAPI is to "adapt" your domain to a specific technology such as HTTP. WCF can be thought of as implementing an open host service in DDD lingo.
You mentioned WebAPI which is an alternative if you want HTTP. Most importantly, be aware of the role of this adapting layer. As you state, it is best to have the UI depend on DTOs and generally the contract of a service implemented with WCF or WebAPI or anything else. This keeps things simple and allows you to vary implementation of your domain without affecting consumers of open host services.
You should always be on the lookout for needless complexity. Layering is a trade-off and sometimes it can be overkill. For example, in an app that is primarily CRUD, there is no need to layer this much. Also, as stated above, don't think of WCF services as being application services. Instead, think of them as adapters between a transport technology and application services. In turn, think of application services as being a facade over you domain, regardless of whether your domain is implemented with DDD or a transaction script approach.
What really helped me understand is the referenced article on the hexagonal architecture. This way, you can view your domain as being at the core and you layer things around it, adapting your domain to infrastructure and services. What you have seems to already follow these principles. A great, in-depth resource for all of this is Implementing Domain-Driven Design by Vaughn Vernon, specifically the chapter on architecture.
Does implementing a layered architecture like this really involve so much mapping, or have I missed something?
Yes. The thing is that it's not the same object. It's different representations of the same object, but specialized for each use case. A view model contains logic to update the GUI, a DTO is specialized for transfer (might get normalized to ease transfer). etc. etc. They might look the same, but they really aren't.
You could of course try to put all adaptations into a single class, but that would not be very fun to work with when your application grows.
Is it recommended (or even smart) to use a Wcf service to run the main logic like this (it practically is my Application Service)
You need some kind of networking layer. I wouldn't let all client applications touch my database. It would create a maintenance nightmare if you mess with the database schema (if some of the clients still run the old version).
By using a server it's much easier to maintain version differences.
Do note the a WCF service definition should be treated as constant once being used. Any changes should be defined in a new interface (for instance MyService2).
Are there alternatives to Wcf without having my domain objects in my UI layer?
You could take a look at my framework. Start post: http://blog.gauffin.org/2012/10/writing-decoupled-and-scalable-applications-2/
Is there anything wrong with this implementation.
Not that I can see. Looks like you have a pretty good grasp of the concepts and how they should be used.
Any fall pits to look out for?
Don't try to be lazy with the queries and commands. Don't make them a bit more generic to fit several use cases. It will come back and bite you when the application grows. Smaller classes is easier to maintain.
Do you have any good examples to recommend looking at that can help me to understand how all these concepts are supposed to work together.
The my linked blog post and all other articles in that series.
I need to write server & client part. I need guidance how to start with WCF web-services.
I need to create WPF application that at the beginning will be simple UI for database tables, but later will consume data from server as WCF services.
I was looking at LightSwitch, but it seems impossible to integrated it later with server part.
In Visual Studio 2010 after I create WPFApplication1 project I have Data Sources docked window.
Then I can add new data source and select services
What kind of WCF services should I create for WPF application?
I would like something like WCF RIA Services / Domain services, but they are only for RIA.
At least no support from Microsoft. What is classic way for creating services for WPF application?
Related questions are :
Hosting WCF Rest Services in WPF Application
Architecting a WPF application with WCF Data Services
How to use WCF RIA SERVICES with WPF application?
WCF, Web services or ADO.NET data services: What shall I use?
I would suggest you to create four projects for that porpouse:
Yourapp.UI (XAML code and ViewModel)
Yourapp.Data (Data Access Layer)
Yourapp.Entities (Definition of your business objects)
Yourapp.Services (Services Layer aka WCF)
Yourapp.Data talks to database and retrieves the desired information.
Yourapp.Services maps and transforms that information into your entities (if the logic involved is too complex, perhaps and aditional business layer would be required).
From Yourapp.UI just need to add a Service Reference and consume it like a IEnumerable<> and make it reusable so VS won't create additional objects but point to your entities.
Yourapp.Entities must be referenced in projects 1,3 and 4. This will make your development easier to test and debugable. Also try to use interfases at the service level so mock testing would be easy to implement.
Hope I was clear enough, I'm kind of tired. If any question aroses, add a comment please. Cheers.
Ok, I know it was more a theory answer rather than a practical one. May I suggest you to check these tutorials? MVVM Tutorials - WCF/WPF They are excellent introduction and happens to use WPF and WCF like you require.
A couple of months ago I found them in youtube and believe me, they cleared out a lot of doubts I had at that moment. Since then it's been a lot easier to master. At the beginning WCF can seem more complicated than what it really is.
Sorry for not extending my answer but I don't have much time at this moment. Hope it make more sense now.
I am having a bit of trouble finding relevant and updated information. A lot of what I find is from 2001/2002, and the majority of it doesn't apply.
Basically, I want to create a server/client application. The server will be run from a single dedicated machine, and I will install the client on numerous other machines (remotes).
What I am not sure on (never used ASP.NET Web Application) is do I need to plan ahead for it, or can it be added on top?
I am assuming I can just create the Server/Client applications in C# NET, then create the ASP.NET Web App later to give a web based front end to the server application. If this is correct, can anyone possibly link me to good resources for this type of information? As I mentioned, everything I have found is either old, or doesn't apply.
Ok I think I get what you're asking even though it's not that clear.
You're looking to build a cliet/server application initially and later to provide similar functionlaity via a web based application. Correct? If so, then:
To some extent you do need to plan and design for it. This is what I recommended: Let's assume you're using a layered architecture for you server side application and these layers are:
1. TCP/IP Interface layer
2. Business layer
3. Data layer
The business layer and data layer will be reused in your ASP.NET application as well. Both these layers MUST be completely agnostic of and TCP/IP and Http stuff.
The TCP/IP interface layer, sort of translates the TPC/IP ness of your server application to pure C# method calls to normal data types and makes calls into your business layer. If you follow this basic design you will be able to reuse your business layer and data layer.
EDIT
ASP.NET applications are assemblies. They run in the process space of another "application" (worker process) that in turn runs in the process space of IIS. But nonetheless, the architecture I mention in my answer will work for you (I do this all the time) if you're careful about your TCP/IP Interface layer being the barrier (and interface) or in order words decoupling your TCP/IP "ness" from your business layer.
For example, an aspx page (or MVC controller or asp.net handler) is an "Http Interface layer". If used correctly, the "page" handles all of the http/html stuff and "converts" all of the messaging into regular C# method calls on the business layer completely decoupling the business layer from any knowledge of ASP.NET, http, sessions and the like. The business layer in fact should have know knowledge or dependency on anything to do with ASP.NET.
So if your TCP/IP service interface layer performance the same function (that is the sole responsibility of Service interface layers) then you're good to go. And when the time comes, you'll slap on an Http Service interface layer to your system (sharing the BL and DAL). Hope that makes sense.
It's very common to have more than one project in an ASP.NET based web site, some of which have really nothing to do with the WEB UI.
A good resource on this will be any beginner's ASP.NET tutorial. (I trust your googling skills :-)).
Just make sure you separate the GUI from the implementation (for example - if you use webForms to test it - make sure you don't rely on any webForms specific implementation).
I really recommend reading a bit about ASP.NET before starting the task, but generally, rest assured your c# projects are "pluggable" to an ASP.NET implementation.
Hope I got the question right..
http://www.asp.net/general/videos
http://msdn.microsoft.com/en-us/library/ms178093(v=VS.90).aspx
You don't have to create any client application, the client is the web browser.
Okay people, here's another one for ya'll:
I'm starting in the n-tier apps world. I've done some reading on the topic and general advice is that n-tier apps' objective is to abstract functionality tween layers. So, based on this, in a n-tiered app the regular model is:
Data Access -> Business Layer -> Presentation
Since I'm a .NET developer, I thought that to enhance integration with multiple client types (Silverlight, Web app or even a WinForms client) I should use WCF (Windows Communication Foundation) as data services at the business layer so clients can communicate to it regardless of its type. Also, I'm a huge fan of NHibernate as a ORM. So my structure goes like this:
Data Access (NHibernate) -> Business Layer (WCF) -> Presentation (WPF, ASP.NET, WinForms
Okay, so that is the setup. I'm a total newbie in this kind of approach, so I thought I could post here requesting for advice on this setup. Also, I'm very confused on how to setup this in a VS solution, I like to separate layers in different projects, but what about abstraction of data objects (like Customer, Order, etc.)? Do I put em in a separate library? And what about WCF? I know is a programmer's sin to transfer the data classes over the wire to the client. What's the professional's way to achieve this?
Thanks, any advice would be very appreciated.
That's pretty much on target. N-Tier is a bit more complex than N-Layer however, and can be contrasted by asking, "Are your layers actually living on separate physical servers?"
Depending on how complex your Business layer is, you might want to abstract it further between a Business and Service layer. Typically those two are tied very closely and live on the same physical server. The service layer often acts as a Facade to your BLL.
If you're Presentation layer is on the same server, than your ASP.NET or WinForms apps might want to communicate with the BLL without going through WCF services.
Read up on Microsoft Patterns & Practices - Application Architecture Guide.
Your Domain objects should live in their own assembly typically your domain model. According to Microsoft Framework Design Guidelines, it's good practice to name your project assemblies accordingly:
[Company].[ProductOrComponent].[...]
I happen to like this format of name-spacing and generally use:
[Company].[Product].[Layer].[SubLayer].[...]
Here is an example solution using solution folders to organize each project:
In this example, I have a BLL and Service layer. The Service layer provides the actual implementation in a WCF Library while the Presentation actually contains the WCF Web application to host the services. It's always good practice to split up implementation from interface.
The /Client folder can be ignored, I just use that as a sample console app for testing. Any Client applications that consume your service should probably have their own solution or you're going to be managing a huge solution.
As for your data object being transferred over the wire... I'm assuming you mean the classes from your ORM. (Domain Model) You're correct its generally considered bad practice. The solution is using Data-Transfer Objects. You can see from the picture I have a .Dto library. If you're able to use tools like AutoMapper, than I'm all for it, however, adding DTO's to your solution brings with it further complexity and maintenance. I believe Dino Esposito wrote a good article on the subject. Will try to find it for you.
Hope this helps.
[EDIT]
I should note, I'm unfamiliar with nHibernate's capabilities. There might be better solutions for using that ORM. I've only worked with Entity Framework.
[EDIT 2]
Check out Dino Esposito's - The Pros and Cons of Data Transfer Objects
Can anyone confirm the best way to integrate the repository pattern with webservices.... Well actually i have my repository patter working now in c#. I have 3 projects, DataAccess, Services and my presentation layer.
Problem is my presentation layer is a number of things... I have a ASP.NET MVC site, I have an WPF application and we are about to create another site + an external company needs access to our repository also.
Currently i have just added the services layer as reference to each of the sites... But is not the normal way to provide data access via web services? (WCF) - if this is the case will this break the services layer? or should i convert the services layer to a web service?
Anybody know what the PROS and CONS are of this, speed??
I think I understand your dilemma. If I understand correctly then your services layer consists of pure fabrications. http://en.wikipedia.org/wiki/GRASP_(Object_Oriented_Design).
If I assume correctly above, then your services layer should not be impacted at all by the introduction of WCF. WCF is essentially an additional presentation layer that provides interoperability, sitting between your UI presentation layer and any business logic layers. So your WCF services would then call your services layer, which may access repositories as needed.
WCF provides a high degree of interoperability so I think it is an excellent choice. I would use basicHttp bindings though, if you intend to interop with different programming languages as this is the most flexible. Don't worry about the speed. There are plenty of solutions out there to mitigate any bottlenecks that result due to WCF.
Good luck, and let me know if I can help in any other way.
Well first - not all callers have to use the same repository API; this is especially true of an external company.
WCF is interface based. This means that if you need to re-use some logic code, it is possible to use IoC/DI to inject WCF rather than a DAL (but using the same interface) - by using assembly sharing. It sounds like this is what you are doing. This works in many cases, but not all; fundamentally web-service based APIs often need to be designed differently in order to be optimal. It also isn't 100% pure from an SOA viewpoint, but it gets the job done, and allows more intelligent domain entities, so in an intranet (etc) scenario it is (IMO) perfectly reasonable.
An external caller would typically just use the wsdl/mex-based APIs (rather than assembly sharing), but anything is possible...
Maybe webservices are not the best way, if i have full access to the service assembly then i suppose it always better to assembly share the services layer with my applications.
My applications do similar things, but they all need to access the service layer - well the business logic and get back information...
In this case - its always preferable to use assembly sharing with the service layer rather than provide a WCF Web service using HTTP protocol or using TCP on wcf - for example?
Thanks again
Whether to share your Service/API assemblies with your client applications is fairly subjective. If you are a full Microsoft shop, and use .NET for your entire application stack, then I would say sharing the API is a great way to gain code reuse (you have to be careful how you design your API so you don't bleed domain concerns, like repositories, into your presentation.) If you don't have any plans to migrate your client applications to other platforms (i.e. you plan to stay on .NET for the foreseeable future), then I think its perfectly acceptable to share your Service/API assemblies (and even then, in a multi-platform client environment, sharing Service/API with .NET clients should still be acceptable.) There is always a trade off between the 'architecturally ideal' and the 'practical and achievable within budget'. You can spend a LOT of time, money, and effort trying to achieve the architecturally ideal, when the gap between that and the practical often isn't really that much. The choice NOT to share the API and essentially recreate it to maintain "correct" SOA, consuming only the contract, can actually increase work and introduce maintenance hassles that quite possibly are not worth it for your particular project at this particular time. Given that you are already generally 'service-oriented', if at a future point in time you need the benefit that contract-only consumption on the client can offer, then your already set to go there. But don't push too far too soon.
Given your needs, from what I have been able to glean from these posts so far, I think your on the right track from your services down too. A repository (a la Evans, DDD) is definitely a domain concern, and as such, you really shouldn't have to worry about it from the perspective of your presentation layer. You services are the gateway to your domain, which is the home of your business logic. Repositories are just a support facility that helps you achieve domain isolation from a data store (they are glorified collections really, and to be quite frank...they can be a bit of a pain in a dynamic and complex domain. Simple data mappers, (Fowler, PofEAA) are often a lot easier to deal with and less complex in the long run, and allow more adaptable behavior around your data retrieval logic to be centralized in your domain services.) Aside from heavy use of AJAX calls to REST Services, if you expose adequate Services/API around your domain, that is the only thing that your clients should have worry about. Wrap up all the rest of your business logic entirely within the confines of your domain, and keep your clients as light weight as possible and abstracted from concepts like 'Repository' or 'Data Mapper' and whatnot.
In my experience, the only non-service or API concept that needs to be shared across the Client-to-Domain boundary is Context...and it can be notoriously difficult to cross that boundary in a service-oriented application.