Creating a SOLID Visual Studio Solution
page 5 of 6
by Steven Smith
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 50036/ 78

Solution Organization

Our solution is going to include the following projects:


The Core project holds almost all of the interfaces used, as well as your Model objects, which should be Plain Old CLR Objects (POCOs).


The Infrastructure project holds your implementations of various interfaces for things that need to communicate outside of your process.  These include web services, database access repositories, email routines, system clocks, file system, etc.  Just about anything that I've discussed on my blog as being a dependency should have its implementation in the Infrastructure project.

Infrastructure depends on Core.


Your UI project.  This might be a web project, Windows Form, WPF, Silverlight, or even Console Application.  You might even have multiple UIs within your solution.

UI depends on Core and Infrastructure (at least transitively).  If you are not using a separate DependencyResolution project, then UI will need to provide the actual implementations from Infrastructure to plug into the interfaces it uses.


These are the only projects you *need* to have.  However, I usually include the following as well:


You might create multiple unit test projects.  However, unit tests should not reference Infrastructure, typically, because they are meant to only test your code, not dependent code.  Integration tests (see below) should be used to test how your code interacts with other systems.  If you only create one UnitTests project for your whole solution, you will want it to reference Core and any other project you are testing.


Integration tests are automated tests that verify how your application works with other systems (like your database) outside of your running process.  It should reference your Core, Infrastructure, and DependencyResolution projects and should ideally use the same object graph that you will use in production (or something close to it).


This project is simply responsible for handling registration of types and interfaces and resolving types that have dependencies.  That is, if you use the Strategy pattern to say that a particular class requires an IFileSystem as part of its constructor, you can wire up the WindowsFileSystem class to the IFileSystem interface in the DR project, and then use the DR project to create your class such that it will automatically have its dependency provided (as a WindowsFileSystem instance).  This project will generally comprise just a few classes and your Inversion of Control Container of choice (e.g. StructureMap, Unity, NInject, etc).

DependencyResolution should reference Core and Infrastructure.

These next screenshots show the sample solution, which includes all of the moving parts, working DependencyResolution, working Integration Tests, and working Unit Tests.  The focus here is on the references between the projects.


You can run the sample, which deals with events that have a start and end date and a service that lists current, expired, or upcoming events, either by running the console application or by running the unit or integration tests.  The console application pre-loads a few events and then updates every 15 seconds with a listing of each category of event.  The unit tests verify whether a given test event is active, expired, or upcoming by allowing you to fake the current time.  The integration tests use the system clock and an in memory listing of events, wired up via DependencyResolution, to test the service.

In the interests of keeping the number of dependencies to a minimum, I didn't install a mocking framework (Moq or Rhino Mocks, for example) for use in the UnitTests project.  I recommend running 'install-package moq' from the Package Management Console to get started using Moq if you don't want to hand-write lots of fake implementations.  I also tend to prefer NUnit but stuck with the built in MSTest, in order to keep dependencies to a minimum.

You can learn more about creating a multi-project solution template for VS2010 here.

View Entire Article

User Comments

Title: :)   
Name: hi
Date: 2011-12-10 6:29:57 AM
the sample link broken
Title: :)   
Name: ChrisA
Date: 2011-06-15 11:55:02 AM
I agree with everything you said...
Title: :)   
Name: ChrisA
Date: 2011-06-15 11:12:05 AM
Sorry... Not meaning to rip your examples, since you are doing a good thing by trying to help people learn...

I just have wanted to have a serious discussion with someone about this since my opinion has been getting pretty strong with all the code I keep seeing that drives me crazy...

Title: We Actually Agree   
Name: Steve Smith
Date: 2011-06-15 11:12:05 AM
I think we pretty much agree. Let me ask and answer some questions myself this time.

Does the sample app in this article *need* any IOC container? Nope. Again, it's just there so people see how it's wired up.

Should you always start with an IOC container? Always? No. Like everything else, It Depends. But if you and your team are comfortable with them and you know the application is going to be of sufficient scope that in your experience one will be beneficial, then it's not a YAGNI violation to start with it. If you're not sure or lack that experience, start without, or gain experience with them in a spike solution (perhaps using my sample here as a starting point).

Do people mis-use and over-use IOC containers? Yes. Can they lead to over-complicated solutions? Yes. Are they rather "trendy" at the moment amongst .NET developers? Yes. Does that mean we definitely should or should not use them? No - use your judgment.

You disagree with much of this?
Title: :)   
Name: ChrisA
Date: 2011-06-15 10:52:29 AM
1) I do think they have their uses for this, but I think that in a lot of cases it leads to a lack of understanding of how to properly architect a solution. Yes it makes it easy to resolve dependencies sometimes on complex object graphs, but is that a good thing? Depends... Could lead to someone not understanding how the application works very well and if it is not necessary and adds confusion I say get rid of it...

2) There is a lot of validity in this if you mean a "correct" usage of IOC containers and only when "needed"... I just inherited a project and stripped out StructureMap.. It was a huge issue in the app, served no purpose and had actually confused the previous developer... Someone told him he needed to "wire up" his app with StructureMap... So he did...

You are able to achieve the SOLID principles in your example without the IOC container... Right now I would argue that the IOC container is just an illusion of decoupling....

Remove the reference to Infrastructure and then run your tests or UI... Yeah you are decoupled...

I have used an IOC container in one application and that was to facilitate automated testing in the UI... I didn't need it in any of the unit tests or integration tests... I needed to be able to plugin mock services to what was normally a live application... I needed the ability to instantiate based on the config file... Outside of that, in the extremities of my application (tests, ui) most times I need only 1 ISomething, I know what that ISomething is, I have a ref to the project and I just instantiate it... Why use an IOC container... What is going to change that I am going to want one later? YNGNI?????

I just see a huge amount of overuse and I really think it leads to bad architectural practices...
Title: Questions for you   
Name: Steve Smith
Date: 2011-06-15 10:31:32 AM
So, two questions for you:
1) Do you think that IOC containers are good at managing object graphs and reducing coupling within complex applications?

2) If so, do you think it's more likely that an application will evolve in a testable and loosely-coupled manner with an IOC container managing these dependencies from the start, or if some months down the road the team needs to decide whether to try and incorporate one into an app that hasn't been using one and thus requires touching a large percentage of the codebase in order to eliminate direct instantiations, etc. (and of course at this point the team is under deadline pressure, etc.)?

I realize the 2nd question is somewhat loaded...
Title: mister pickles   
Name: ChrisA
Date: 2011-06-15 10:21:59 AM
I understand the need to include it, but I guess I feel that people rely on IOC containers in bad ways and your example seems to add to the problem...

In your test you know that you need a certain mock/object/etc to fulfill your interface contract (perhaps done through constructor injection for DI...) Just instantiate it in the test... What purpose does the IOC container make... You are still coupled to the IOC container and its config, and this gives you no benefit in the particular test... In the UI, same thing... You add a ref to the project to basically "hack copy" the dll to the directory so you can jump through hoops to load an object through the container, when you won't just use the dll reference you have... For what? unless you need two ISomethings in your UI and your config sets the dependency I can't see the reason to rely on a container so much...

I have continually seen how overuse of an IOC container leads to ridiculously confusing applications... Go without until you need it to solve a problem... Now people start their app with an IOC container... silly...
Title: KISS and Experience   
Name: Steve Smith
Date: 2011-06-15 9:38:37 AM
I agree with the KISS principle, however my intent with showing the inclusion of the IOC container in this example is to demonstrate to readers how a real-world non-trivial solution looks, while still being small enough to comprehend. Do I need one for this "application"? Of course not. But there are very few examples out there of solution structures that are both small and simple yet include the basic necessities of building a loosely-coupled application, and for any application of reasonable complexity, IOC containers like SM help. Now, if you're not unit testing, not using the strategy pattern, and/or not using interfaces, then of course you can just skip this whole thing and keep building things in the UI->BLL->DAL manner. It works, it's just not easy to test or refactor without touching the database.
Title: master of ceremony   
Name: ChrisA
Date: 2011-06-15 8:25:13 AM
IOC containers are overrated... In this instance, you can remove DependencyResolution and StructureMap. Unless you have services/plugins that need resolving or the same EXE needs to be able to be configured differently, I would argue IOC containers add too much complexity and confusion... Boy are they the flavor of the month though...

In your UI, you know what you need, so instantiate the objects and get rid of the IOC container... Same in your tests... When you need an IOC container, then use it... You don't need it, don't use it... Keep your Core/UI/Infrastructure architecture, but KEEP IT SIMPLE SILLY... KISS should be the overarching principle...
Title: (no title)   
Name: James Peckham
Date: 2011-06-14 6:46:32 PM
You're right. Excuse my previous post...

i was definitely confused. The diagram showing data and ui referencing business got me 'excited'.

i think i'm trying to link things that have nothing to do with eachother... such as class library/solution layout and SOLID.

Thanks for this post it's got me re-reading rob martin's agile patterns & practices in c# book...chapter 28.
Title: IOC?   
Name: Steve Smith
Date: 2011-06-14 5:44:08 PM
MSTest has fewer external downloads if you already have the correct SKU of VS installed, is what I meant. Though with Nuget, it's less of an issue to pull in dependencies. I'm toying with adding this as a Nuget package if I make it a proper VS installer, at which point I'm sure I'll make a "lite" one and one that has the third-party tools I prefer to use (like NUnit and Moq and AutoMapper).
I don't see how this design "breaks Inversion of Control". I'm not even sure what you mean by that - can you elaborate? Certainly by having everything depend on Core, which houses the abstractions, I'm following DIP, which is all I claim in the article. And my IOC Container works just fine everywhere I need it to, but I don't think you're referring to Inversion of Control in the context of an IOC container...
Title: (no title)   
Name: James Peckham
Date: 2011-06-14 5:39:07 PM
Also i believe having your Ui and Data layers depending on your business layer is also incorrect and breaks Inversion of Control. What you really want to have is a project (class library) of UI contracts/abstracts, Business contracts/abstracts, and data contracts/absstracts. Then the dependencies are inverted toward the "top most" package being in control of injecting them.
Title: (No Title)   
Name: James Peckham
Date: 2011-06-14 5:35:27 PM
Just curious... why do you make the assertion that MSTest has less dependencies than NUnit? or do you simply mean 'less to download and configure'?

Product Spotlight
Product Spotlight 

Community Advice: ASP | SQL | XML | Regular Expressions | Windows

©Copyright 1998-2020  |  Page Processed at 2020-02-19 5:19:00 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search