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..
Related
I was wondering what the naming convention for an Interface sub project within a solution would be. I know interface files start with an "I", does this apply to projects as well?
I have separated the interface into a separate project to keep the solution organised, as opposed to creating a interface file within the project which would be implementing the interface.
All files and projects are contained within one solution.
I apologise if this doesn't read well.
This is a common pattern for organizing solutions with many projects. However, there is some debate whether (in some cases) it is worth it.
I've seen a few different naming conventions used:
Inc.Project.Contract
Inc.Project.Contracts
Inc.Project.Interface
Inc.Project (like a base project that is a common dependency)
Inc.Project.Common
This is the way MS uses it <Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]
For example, Microsoft.WindowsMobile.DirectX. see link http://msdn.microsoft.com/en-us/library/ms229026.aspx
I agree with the naming convention that dtryon wrote in its answer.
But do not over-engineer the design of your solution. If you don't need to reference your interface from multiple projects, I don't think separating your interface in its own project is useful. It adds complexity but very few benefits.
Same thing for the interface file itself: if you do not plan to reference an object instance using the interface type (and not the type of the object that actually implements the interface), the interface isn't really useful.
I usually follow a pattern of ...
MyAppSolution - empty solution
MyApp.App - client facing application
MyApp.Adapters - project containing interfaces
MyApp.DAL - the data access layer
That's usually as simple as I make it ... If things are more complex, I may have a services project or a business rules project or something of that nature ... the reason I use an interface project is that I want the client application to be completely ignorant of the back end implementation; that way if I need to change an implementation, the client is not affected (does not have to change) as long as I don't change the interfaces ... And, this really happens ... I have changed DBMS's before, I have changed from a DBMS to an API, etc ... When initially building out an app, the extra layer of abstraction can seem like overkill until you need it, then it is a god send ...
I have a sample ASP.NET application. The appliaction was developed as POC and not following any design and architectural standards.
Now I want to restructure the application. I can see some of the business logic and controls can be reused in future, such as login control.
I have two options for restructuring
I create a Utility DLL that will contain all such resusable code and another DLL that will contain all controls that can be reused.
I will create a separeate DLL for each type which can be reused e.g. Login control.
Which option is more better. Although I feel option 1 is good, but I need suggestion from experts.
I have no idea why you would want to keep a separate assembly per type. Don't do that.
Keep related functionality together in a single assembly. Look at how the .NET Framework is organized for examples. Note how, if you're not doing data access, you don't need to reference System.Data.dll.
There are multiple ways to build an architecture. For instance you can create horizontal layers which put all GUI logic, business logic and data logic into separate layers. This is only from logical perspective. Where to put the layers is another question. From OO perspective you put them in at least different classes. You can decide to put them in different name spaces, different project/assemblies.
Just start slowly and refactor the most obvious parts. You can start putting the classes together in a part of the project (folder). Then change namespaces. Then put them in seperate project. Small actions will give you the chance to further consider your options. Each improvement is one.
So my advice is to first arrange classes and namespaces within the current project and so shape the logical parts. Maybe you need to add some interfaces here and there as well to separate the layers.
I would go for a single assembly for your controls. You might create a new assembly for controls which you probably won't use soon or are very special.
I would categorize the business logic and make an assembly for each category.
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).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
We work on a middle-size project (3 developers over more than 6 months) and need to make following decision: We'd like to have interfaces separated from concrete implementation. The first is to store the interface in a separate file.
We'd like to go further and separate the data even more: We'd like to have one project (CSPROJ) with interface in one .CS file plus another .CS file with help classes (like some public classes used within this interface, some enums etc.). Then, we'd like to have another project (CSPROJ) with a factory pattern, concrete interface implementation and other "worker" classes.
Any class which wants to create an object implementing this interface must include the first project which contains the interfaces and public classes, not the implementation itself.
This solution has one big disadvantage: it multiplies the number of assemblies by 2, because you would have for every "normal" project one project with interace and one with implementation.
What would you recommend? Do you think it's a good idea to place all interfaces in one separate project rather than one interface in its own project?
I would distinguish between interfaces like this:
Standalone interfaces whose purpose you can describe without talking about the rest of your project. Put these in a single dedicated "interface assembly", which is probably referenced by all other assemblies in your project. Typical examples: ILogger, IFileSystem, IServiceLocator.
Class coupled interfaces which really only make sense in the context of your project's classes. Put these in the same assembly as the classes they are coupled to.
An example: suppose your domain model has a Banana class. If you retrieve bananas through a IBananaRepository interface, then that interface is tightly coupled to bananas. It is impossible to implement or use the interface without knowing something about bananas. Therefore it is only logical that the interface resides in the same assembly as Banana.
The previous example has a technical coupling, but the coupling might just be a logical one. For example, a IFecesThrowingTarget interface may only make sense as a collaborator of the Monkey class even if the interface declaration has no technical link to Monkey.
My answer does depend on the notion that it's okay to have some coupling to classes. Hiding everything behind an interface would be a mistake. Sometimes it's okay to just "new up" a class, instead of injecting it or creating it via a factory.
Yes, I think this is a good idea. Actually, we do it here all the time, and we eventually have to do it because of a simple reason:
We use Remoting to access server functionality. So the Remote Objects on the server need to implement the interfaces and the client code has to have access to the interfaces to use the remote objects.
In general, I think you are more loosely coupled when you put the interfaces in a separate project, so just go along and do it. It isn't really a problem to have 2 assemblies, is it?
ADDITION:
Just crossed my mind: By putting the interfaces in a separate assembly, you additionally get the benefit of being able to reuse the interfaces if a few of them are general enough.
I think it you should consider first whether ALL interfaces belong to the 'public interface' of your project.
If they are to be shared by multiple projects, executables and/or services, i think it's fair to put them into a separate assembly.
However, if they are for internal use only and there for your convenience, you could choose to keep them in the same assembly as the implementation, thus keeping the overall amount of assemblies relatively low.
I wouldn't do it unless it offers a proven benefit for your application's architecture.
It's good to keep an eye on the number of assemblies you're creating. Even if an interface and its implementation are in the same assembly, you can still achieve the decoupling you rightly seek with a little discipline.
If an implementation of an interface ends up having a lot of dependencies (on other assemblies, etc), then having the interface in an isolated assembly can simply life for higher level consumers.
They can reference the interface without inadvertently becoming dependent on the specific implementation's dependencies.
We used to have quite a number of separate assemblies in our shared code. Over time, we found that we almost invariably referenced these in groups. This made more work for the developers, and we had to hunt to find what assembly a class or interface was in. We ended up combining some of these assemblies based on usage patterns. Life got easier.
There are a lot of considerations here - are you writing a library for developers, are you deploying the DLLs to offsite customers, are you using remoting (thanks, Maximilian Mayerl) or writing WCF services, etc. There is no one right answer - it depends.
In general I agree with Jeff Sternal - don't break up the assemblies unless it offers a proven benefit.
There are pros and cons to the approach, and you will also need to temper the decision with how it best fits into your architectural approach.
On the "pro" side, you can achieve a level of separation to help enforce correct implementations of the interfaces. Consider that if you have junior- or mid-level developer working on implementations, the interfaces themselves can be defined in a project that they only have read access on. Perhaps a senior-level, team lead, or architect is responsible for the design and maintenance of the interfaces. If these interfaces are used on multiple projects, this can help mitigate the risk of unintentional breaking changes on other projects when only working in one. Also, if you work with third party vendors who you distribute an API to, packaging the interfaces is a very good thing to do.
Obviously, there are some down sides. The assembly does not contain executable code. In some shops that I have worked at, they have frowned upon not having functionality in an assembly, regardless of the reason. There definitely is additional overhead. Depending on how you set up your physical file and namespace structure, you might have multiple assemblies doing the same thing (although not required).
On a semi-random note, make sure to document your interfaces well. Documentation inheritance from interfaces using GhostDoc is a beautiful thing.
This is a good idea and I appreciate some of the distinctions in the accepted answer. Since both enumerations and especially interfaces are by their very nature dependency-less this gives them special properties and makes them immune from circular dependencies and even just complex dependency graphs that make a system "brittle". A co-worker of mine once called a similar technique the "memento pattern" and never failed to point out a useful application of it.
Put an interface into a project that already has many dependencies and that interface, at least with respect to the project, comes with all the dependencies of the product. Do this often and you're more likely to face situations with circular dependencies. The temptation is then to compensate with patches that wouldn't otherwise be needed.
It's as if coupling interfaces with projects having many dependencies contaminates them. The design intent of interfaces is to de-couple so in most cases it makes little sense to couple them to classes.
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.