We are going to be developing a large enterprise desktop application very soon and i have been spending some time researching the WPF + PRISM + MVVM approach, i have got a good grasp on most of the concepts and am loving the modularity it provides.
Where i am having problems is with how to architect the services layer to get data in and out, especially when this service is introduced by a module with the idea that dependant module can use it.
I wanted to abstract my WCF data services inside of application services and use ServiceLocator
to resolve concrete instances from within my view-models, however im having a hard time working out how this should hang together, mainly due to my entites being part of the WCF service.
For example
Module1 Contains WCF Service + Concrete Application Service(ISearchService) + WCF Service generated entities(model)
Module1.Infastructure - Contains the following interface for the application service
public interface ISearchService
{
ObservableCollection<Person> Search(string search);
}
this would be registered in the UnityContainer so that any other module can get the concrete implementation introcuded by the module.
My problem is that the Entities (Person
) are defined in the module itself (in the WCF service), so introducing a service and then expecting any other modules to be able to use it means they need to reference the module itself not just the modules infastructure, unless i pull out the services into another assembly.
Should i be exposing my entites that are auto generated from my EF model in this way?
Does anyone have a better solution ?
Here is how did it.
I'm currently using Silverlight + PRISM + MVVM + WCF (RIA) services.
With the current project architecture
Application.RIAServices : This is the project that contains the auto generated classes from WCF RIA services web project. I can reference this project in both WPF and Silverlight.
Application.RIAServices.Web : Webproject containing the DomainServices and database generation code by using the DbContext. this is the WCF RIA link project for Application.RIAServices
Application.Infrastructure : This is where it starts. Because just like you I have a Person/Customer Service using an interface ICustomerService. Because I want to use this service for example application wide and not only in the ModuleA, I place this interface in the Infrastructure. All projects contain a reference to this project.
Application.Modules.ModuleA --> Application.Modules.ModuleD : General modules providing functionality. All of my modules (that use WCF RIA Services) have a reference to the Application.Infrastructure and Application.RIAServices projects.
Application.Shell : Startup project. having the bootstrapper and registering all relevant modules.
Reading Rachels question made me think about certain things and I just wanted to leave my structure on how I did it. You might have an idea about it. I Don't want to go to DTO yet because things like validation are so good intregrated in WCF RIA services that it automaticly reflects in the textbox when something is wrong and displaying an error message. Looking forward to hearing your opinion and the outcome of the question/issue
Edit:
Application.Domain also has a separate structure aswell.
I have my Models. Only container pure properties that need to be mapped to the database. Then I have my Metadata folder. Now for this to work I need to have the same namespace as my Entity and I make the entity partial. I create a Entity.metadata.cs file and in there I create a internal sealed class EntityMetaData
, Copying the properties and adding attributes to it them. By using the MetadataType
attribute above the Entity class it adds all those attribute to the EF/WCF RIA code generator.
One of those attribute is the CustomValidation
it use a static class and a method paramater and validates the entity on the server. Or if you create the file with a .shared.cs extension it gets generated to the Application.RIAServices project.
Possibility
To try to answer your question, you might have only 1 option and that is what you suggested at first. You can create a Customer.Infrastructure Project.
this project contains the interface for the ICustomerService, the Entity/DTO/POCO what ever you want, and maybe even a implementation of this ICustomerService or the WCF service. This then allows all your modules to reference this project and thus not creating dependecies between modules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With