At our company we are developing an application that will consists of several modules. The architecture is pretty much defined but I have seconds thoughts about the presentationlayer and I would really like to hear your opinions. The architecture is as follows:
Foreach module we create several namespaces and those will be compiled in their own class library. So for our CRM module we create the following:
ProductName.CRM.ServiceLayer (holds the servicecontracts interfaces of CRM module)
ProductName.CRM.ServiceLayer.Implementation (implements the servicelayer interfaces of CRM module)
ProductName.CRM.BusinessLayer (holds the businesscomponents of CRM module)
ProductName.CRM.BusinessLayer.BusinessObjects (holds the businessObjects of CRM module)
ProductName.CRM.DataLayer (holds the DAO interfaces of CRM module)
ProductName.CRM.DataLayer.SqlServer (implements the datalayer interfaces of CRM module)
We create the same structure of class libraries for the modules Finance, HRM, Supply, etc:
ProductName.Finance....
ProductName.HRM....
etc.
I think you will get the idea for now :)
Also we thought about the "Crosscutting Concerns" and for that we create the following namespaces and class libraries
ProductName.Framework.ExceptionHandling
ProductName.Framework.Logging
ProductName.Framework.Security
etcetra...
So that is how our architecture is so far and at this moment I'm trying to find a proper way for setting up the PresentationLayer. For example, should I make a PresentationLayer-library foreach module (ProductName.CRM.PresentationLayer, ProductName.Finance.PresentationLayer, etc.). And make an overall ProductName.PresentationLayer-library who has references to all the other Module.PresentationLayer-libraries. This overall ProductName.PresentationLayer will then have the Login/MainForm functionality and the ability to start forms that are implemented in one of the modules PresentationLayer. It will be like an entry point of the application to other modules.
Or...
Should I make just one ProductName.Presentation-library that contains all forms for all modules. By doing that that I can easly navigate to other forms and don't have to worry about references between modules when they are going to use each others forms (sometimes they will do).
The first solutions sounds good to me. However, when forms from different modules wants to navigate to each other.This kind of functionality will be tough to implement because only one of the two can have the reference to the other.
I would really like to hear your opinions about this issue I'm dealing with and maybe someone could give me a proper solution or idea that I can use.
thanks in advance,
Cheers!
You can always create interfaces that forms implement if they need to exchange data. In fact, it's probably not a great idea to have lots of forms knowing about each other as that creates maintenance and enhancement problems in the long run.
By using interfaces and potentially some kind of Locator service, you can avoid hardwiring dependencies between forms - and then you are free to use either architectural model (1 big assembly vs. many smaller ones).
Related
I am dealing with some architectural design concerns that is needed to be sorted out. My current architecture can be seen below. Each box is a project in visual studio, and they together forms solution.
My Core application is coded in WestCore.AppCore Context, and I have another project group called CSBINS (which includes system web service integrations) CSBINS is an merchant product that is why I found it better to seperate it to another project and only depend it with most commonly used interfaces from WestCore.AppCore.
Right now WestCore.Api does not have any logic in it. All the application logic is handled inside AppCore and AppCore.Csbins
The Problem is I sometimes have need to use WestCore.AppCore.Csbins services inside WestCore.AppCore which causes cross referencing issue.
the best approach right now that I think is to add Endpoint Services into WestCore.Api and move cross platform logic to Endpoint Services.
However I would like to get suggestions and design concerns about going further on this since I am very sure that there would be many design choices.
I am also considering to move common AppCore Interfaces and Classes to WestCore.AppCore.Common so that I wont need to reference whole WestCore.AppCore project to WestCore.AppCore.Csbins.
Why are you using services inside other services - this is probably a bad thing and needs refactoring.
Those CORE projects look like are application services projects, it might help calling them 'WestCore.ApplicationServices', Core implies it belongs at the domain level.
It sounds like you need to impliment an anti corruption layer to integrate with the 3rd party vendor rather than creating a whole new 'domain' context. This should be as straightforward as degining an interface in your domain layer (personally I use the *Gateway suffix to identifiy interfaces that interact with external systems)
Not knowing anything about your domain I would probably start with something that looks like this: (I've assumed the csbins is some sort of payment or accounting gateway)
Also, I would strongly recommend avoiding "Common" and "Shared" libraries at the domain level, you shouldn't need them. Your interfaces and classes are DOMAIN objects and belong in your DOMAIN library. The Application Services should be using domain models directly and having implementation of domain interfaces supplied via Dependency Injection. Hopefully your Domain Models are fleshed out enough that your application service classes are just orchestration wrappers.
I would like to split my C# Web API project, such that a given feature (or a set of features) are maintained in separate projects. Ideally, I would still like to maintain layered separation as well within each feature package.
Example: I would like to ensure there is a separate API project for each main feature (i.e. a business suite would be separated into sales API, inventory API, payroll API etc. etc.). Each feature would be divided into API (top layer), Models (DTO/ViewModels sent and received from/to the API), Service (business logic) and Tests. There could be more layers, i.e. separate layers for entity classes etc.
There is a certain amount of shared code that must be reused within these projects, both on the top layer (such as error handling, logging etc.) and other layers as well (database connections, repositories...).
Does anyone have a good example of how to do this separation, such that everything is DRY, while maintaining a clear separation of features?
Best regards,
Daniel
What you're trying to achieve sounds very akin to a micro-service architecture. Here are some good links that describe what this means..
http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html
http://martinfowler.com/articles/microservices.html#CharacteristicsOfAMicroserviceArchitecture
The idea is to build your system in a modularised manor, where each component can talk to each other, usually over HTTP. Which seems to be what you want to achieve with having "features" each exposing an API. There is a whole heap of material on this so I'd read around it.
As for sharing code between them, this can be tricky. If you're thinking of this in terms of a modularised system, perhaps the shared stuff should be its own "feature"/"component"/"service"/"module" (whatever you want to call it). Or perhaps there is some stuff you just want to pull out into its own project- if so consider building a Nuget package to share common code across the components?
I understand this could be interpreted as an opinion question, but it is technical and a problem I am currently trying to solve.
In the Prism documentation, it is stated that modules should have loose coupling with no direct references, only going through shared interfaces. Like in the following picture:
My issue is, if only a few modules required an IOrdersRepository, the infrastructure is the wrong place for it, as this contains shared code for all of the modules. If I placed the interface in another module, then both modules will need to directly reference that one, breaking the loose coupling.
Should I simply create a library which contains this interface and doesn't follow the module pattern?
Thanks,
Luke
It should be definitely Infrastructure module. Markus' argument is absolutely right - you shouldn't create separate assembly for each shared set of interfaces. It's much more better to have Infrastructure module with a lot of interfaces istead of a lot of modules with some interfaces in each one. Imagine, that one time you will find, that 2 of yours "set of interfaces" should use some shared interface! What will you do? Add yet one assembly for that "super-shared" interfaces? Or combine those modules to one? It's wrong I think.
So - definitely Infrastructure module!
PS. Imagine, that .NET Framework has 1000s libraries - one for collections, anotherone for math functions etc....
UPDATE:
Actually, I use Infrastructure module mostly for interfaces and very basic DTOs. All shared code I move to another assembly (like YourApplication.UIControls, YourApplication.DAL etc.). I haven't enough reasons to do exactly this way, but this is my way to understand Prism's recomendations. Just IMHO.
UPDATE 2:
If you want to share your service so wide - I think it absolutely makes sence to have structure like:
YourApplication.Infrastructure - "very-shared" interfaces (like IPaymentService)
YourApplication.Modules.PaymentModule - "very-shared" implementation of your PaymentService
YourApplication.WPF.Infrastucture - infrastructure of your WPF application (in addition to YourApplication.Infrastructure
YourApplication.WPF.Modules.PaymentUI - some WPF specific UI for your YourApplication.Modules.PaymentModule
YourApplication.WebSite.Modules.PaymentUI - UI for web-site
And so on.. So, your modules will have almost always references to YourApplication.Infrastructure and YourApplication.TYPEOFAPP.Infrastructure, where TYPEOFAPP can be WPF, WebSite, WinService etc.. Or you can name it like YourApplication.Modules.PaymentUI.WPF..
I have been using the Windsor IoC Container for my web-based application, to resolve the data access layer implementation the application should use.
The web application's UI will consist of pages, and each page consists of small units called portlets. (Their concept is somewhat similar to widgets.) These so-called portlets are basically web controls and can be configured in runtime for every page invidually.
The application will ship with some of these built-in, but I would like to enable extending it easily.
I figured out that this mechanism is exactly what MEF is built for. So I decided to implement the system in such a way that it discovers portlets using MEF. Then, I realized that it can also do what I currently use Windsor for, so I decided to ditch Windsor in favor of MEF.
Obviously, I will have to use the DirectoryCatalog, which scans for the .dlls in the app's bin folder and returns everything I need.
I read some tutorials, examples, and all questions regarding MEF in StackOverflow, as well. I figured that the easiest way to use MEF is through the PartInitializer which Glenn Block mentioned in his tutorials, but I realized that it is not in MEF. Actually, it is in the code I downloaded from CodePlex, but in a separate assembly, and only in source, not in binary form. (Does this mean that it isn't a part of MEF? Or what's the point in putting it to a separate project?)
Then, I realized that it is for Silverlight, so it doesn't really help me.
(Or should I just compile that against .NET 3.5, or include it in my project, and I'm good to go?)
So now I have a problem which is the following: where should I put the CompositionContainer in my application?
There is another thing I would like to consider: should I use only one CompositionContainer in the lifetime of the app, or I'm better off creating a container for every time when I need it?
Good questions.
In general in terms of questions about where to put the container, I recommend the following posts: http://blogs.msdn.com/nblumhardt/archive/tags/Container+Managed+Application+Design/default.aspx
In of MEF on the web, web-based apps are a bit tricker because of the request / response nature and scalability concerns. For web you would likely want to have a hierarchy of containers, one root one for the application which is shared, as well as child contianers per-request. The child containers should live and die with the request in order to conserve resources. The shared container contains services that are shared by all callers.
You might check out these articles for more insight into how to do this:
http://blogs.msdn.com/hammett/archive/2009/04/23/mef-and-asp-net-mvc-sample.aspx
http://blogs.msdn.com/hammett/archive/2009/07/15/mef-and-asp-net-mvc-sample-updated.aspx
http://mef.codeplex.com/wikipage?title=Parts%20Lifetime&referringTitle=Guide
As far as PartInitializer, I would avoid using something like it unless you have to. ASP.NET provides sufficient hooks in the pipeline through HTTP Handlers, modules and such to let automatically compose on creation.
The only place i would see using PI on the web would be possibly within a custom user control. PI ships as part of Silverlight 4 and is not available in the box for .NET 4.0. I have created a usable version for .NET 4.0 which you can find here: http://cid-f8b2fd72406fb218.skydrive.live.com/self.aspx/blog/Composition.Initialization.Desktop.zip
HTH
Glenn
I have a large .NET web application. The system has projects for different intentions (e.g. CMS, Forum, eCommerce), and I have noticed a (naive) pattern of calling on another project's class. For example, the ecommerce module needs functionality to generate a file on the fly for products, and I call and reference a method in the CMS to do this, because file handling is really a job for the CMS.
Obviously (and I know why), this is bad design and a case of high coupling.
I know a few ways to handle high coupling, like restructuring the project (although I don't really think this is a robust solution), but what else can I do to reduce high coupling? Any simple tips? Also, it would be good to know why/how they reduce coupling. I use .NET 3.5 and Sql Server 2005 so things like JMS (which I keep coming across in my search for tips on this design issue), are not applicable.
Thanks
BTW,
One of the reasons I ask this is that I have read the previous questions similar to this but usually if a question that has been asked before is asked again, different tips can be learnt as different people reply to the post.
I know of dependency injection/IOC, but I am interested in the small things that can be done to reduce coupling.
How could I choose between using a static class, or an interface-derived class, or the IOC approach when deciding on how to reduce coupling? Also, I could develop a web service which could call a static class - mixing up the approaches in my solution.
The interesting thing is that in my application, I don't want it to be disjointed. So I just have a forum, ecommerce system, and any other module required, but everything has to gel into one site so each module (which is represented as a dedicated project in my Visual Studio solution) needs to know about every other module and work with it. So for example, I might have a module which handles user profiles (working with ASP.NET membership, roles, etc), but this will work with the forum module as a user on the forum will be a registered user on the site (one login throughout), and his or her profile will be coming from the user profile module. This is as opposed to seperate profiles as seen on other sites I've come across).
You should expose web services in those projects who will be needed by other projects. This is kind of the base level idea behind SOA. So, I would just create web services and consume them, which will decouple you quite a bit from how you have it now. Hope this helps.
I'd consider starting by doing an "extract interface" refactoring on the tightly coupled pieces. For example, if using the CMS as a backing store, create an interface that can store things, then create a mediator or adapter class that knows about the CMS, but isolate the logic that knows about the storage mechanism details to just that class.
Then, for testing, you can easily substitute an in-memory store or local-filesystem store that doesn't depend on the CMS being up.
Consider using techniques like dependency injection (See StructureMap, Spring.Net, NInject) to simplify instantiation if a simple factory doesn't give you the flexibility you need.
It sounds like you have a layering problem. Your assemblies should have a single dependency cycle - from least stable to most stable. That allows you to version sensibly. Generally, that cycle would be something like UI (least stable) -> Domain Core (stable) -> Data Access (most stable). You can throw in a Utilities or some infrastructre assemblies along the way, but again - they should be considered more stable than the assemblies dependent on them.
I'd guess your App.ECommerce and App.Cms assemblies are more siblings than layers - so you would not want those to depend on each other, but that doesn't mean you can't reuse functionality. For your particular scenario, you need to push the needed functionality down to a Core or Utilities assembly that both ECommerce and Cms can depend on. If it's a specific implementation that ECommerce provides, then you can push an interface or abstract base class to the Core - and have a higher layer (perhaps IoC container) wire up the concrete Cms.FileCreator class to the ECommerce.IFileCreator dependency.
Get proper abstractions in place as described by others (interfaces, etc). Program against abstractions, not concretions.
Design your classes with Dependency Injection in mind as you have described.
Use an Inversion of Control Container as the mortar between the bricks.
Unity from the Patterns & Practices team complements the Enterprise Library.
Scott Hanselman has a nice List of .NET Inversion of Control Containers.
Well, I don't know anything about .NET, but how about refactoring common code into a separate, underlaying project/layer? Loads of stuff in a web app can be done generically to suit both a CMS, a forum and eCommerce, writing to a file is a perfect example.
Another approach could be to see the forum and eCommerce as modules in a CMS, which would also make sense. Then they could safely use specified API:s of the CMS.