Creating a SOLID Visual Studio Solution
page 1 of 6
Published: 14 Jun 2011
Unedited - Community Contributed
Abstract
The SOLID acronym describes five object-oriented design principles that, when followed, produce code that is cleaner and more maintainable. The last principle, the Dependency Inversion Principle, suggests that details depend upon abstractions. Unfortunately, typical project relationships in .NET applications can make this principle difficult to follow. In this article, I'll describe how one can structure a set of projects in a Visual Studio solution such that DIP can be followed, allowing for the creation of a SOLID solution. You can download the sample solution and use it as a starting point for your new solutions if you like.
by Steven Smith
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 35712/ 78

Introduction

The SOLID acronym describes five object-oriented design principles that, when followed, produce code that is cleaner and more maintainable.  The last principle, the Dependency Inversion Principle, suggests that details depend upon abstractions.  Unfortunately, typical project relationships in .NET applications can make this principle difficult to follow.  In this article, I'll describe how one can structure a set of projects in a Visual Studio solution such that DIP can be followed, allowing for the creation of a SOLID solution.  You can download the sample solution and use it as a starting point for your new solutions if you like.


View Entire Article

User Comments

Title: :)   
Name: hi
Date: 2011-12-10 6:29:57 AM
Comment:
the sample link broken
Title: :)   
Name: ChrisA
Date: 2011-06-15 11:55:02 AM
Comment:
I agree with everything you said...
Title: :)   
Name: ChrisA
Date: 2011-06-15 11:12:05 AM
Comment:
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
Comment:
@ChrisA
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
Comment:
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
Comment:
@ChrisA,
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
Comment:
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
Comment:
@ChrisA,
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
Comment:
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
Comment:
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
Comment:
@James,
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
Comment:
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
Comment:
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-2024 ASPAlliance.com  |  Page Processed at 2024-10-16 12:03:19 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search