0

Has anyone created an empty solution stack for .NET (C#) that incorporates an IoC framework for DI using multiple projects? I've struggled for months to create a good reusable stack that has:

  1. MVC UI web app
  2. Empty BLL project (will add real entities later)
  3. Empty DAL project (will add real daab classes later)
  4. Reference/Search data tier
  5. Includes an IoC framework
  6. Sample usage of DI in a Home controller that can reach all the way to the DAL thru the entity layer or to ref/search tier all thru interfaces
  7. Must NOT set a hard reference of any concrete classes at the UI layer

I've attempted this a few times but I always get hung up at #6 and I'm missing something basic in the structure of the stack. Has anyone managed to do this and have a sample solution to show how it's structured? I can create stacks all day long and add a IoC framework, but completely fail at getting it structured so that no concrete references are added to the UI layer. How else can the interface/concrete resolution of objects take place?

Surely some of you scholars have nipped this in the bud, please share some of this enlightenment with me :-)

ps - I've read Mark Seeman's book more than once.. I understand the concept of Composition Root... but have never seen one in use in an NTier solution and have been unable to implement the theory successfully

What I am looking for is a fleshed out solution stack of multiple projects that can be used as a base to start from. One that implements the composition root successfully and can be used to teach the SOLID principles by doing instead of telling. A solution that brings it all to life. See this question for reference.

Community
  • 1
  • 1
CD Smith
  • 6,597
  • 7
  • 40
  • 66
  • I don't know what you mean by #7. You will find it hard to do much of anything without concrete classes, particularly in MVC which best practice dictates concret View Model classes, and of course concrete controllers and other classes. I also don't understand how you can do 6 if you have no entities to "reach through". – Erik Funkenbusch May 16 '12 at 02:45
  • I think you misunderstood. The concretes exist but cannot be hard referenced in the UI layer. That's the whole idea right? Decoupling so a concrete can be switched out for another concrete implementing same interface. But if the concrete is hard referenced its still a development effort to switch the implementation. So the requirement is to be able to structure the stack so the reference isn't in the UI layer. This is where it gets fuzzy. What is everyone else doing? No ntier solution stacks? – CD Smith May 16 '12 at 02:55
  • Basically the problem that I've seen in every IoC sample is its a single project with many internal classes and interfaces. Let's say all dependencies are ctor injected. But if the concrete class is hard referenced in the project what is there to stop a jr dev from newing up said class instead of using the injected interface? – CD Smith May 16 '12 at 03:03
  • I just meant as an empty solution to start from, the entities will be added later. The empty stack is starting point to build on – CD Smith May 16 '12 at 03:09
  • i found it is hard to do, you'll meet many problems. in the end, it is no more elegant. ref: http://stackoverflow.com/a/10482967/926460 – Timeless May 16 '12 at 03:21
  • I agree. Hard to do but necessary to grow and achieve a solid design for an enterprise class easy to maintain structure. Just because it's hard doesn't mean my only option is to use single project apps. Not in the enterprise where I have literally hundreds of assemblies – CD Smith May 16 '12 at 03:26
  • @CDSmith yes,right.i want to find a way to do it also. lots of seniors say do it when it is necessary. I also want to know the elegant way, here is my question : http://stackoverflow.com/q/9632475/926460 – Timeless May 16 '12 at 03:33
  • I think more than a few of us want to get this right. It's a good question and deserves attention from experts who have achieved building great software using these concepts. – CD Smith May 16 '12 at 03:38
  • I still don't understand your issue. You must reference the concrete classes in your DI configuration, which means you must reference them in the main project. I know of no way to do it otherwise. I suppose it's possible, but I've never seen it done. – Erik Funkenbusch May 16 '12 at 03:42
  • Exactly! If not then all the problem the tight coupling gives you are still truly present. You can't just switch out a dependency without a development effort and recompile. The goal is to reduce recompiling just because I need to switch component A for component B. – CD Smith May 16 '12 at 03:45
  • 1
    No. DI is not about reducing recompiling. It's about reducing coupling in general. You can reduce coupling even within a project, and you get great benefits from it. It's about making objects more testable, it's about reducing cross-object familiarity, it's about stopping leaky abstractions. It has nothing whatsoever to do with reducing compilation. In fact, such a goal is not very feasible, since something has to load the assemblies, and that alone is a hard reference in most cases. I suppose you could use Xml configuration, but that exposes your interals to config files. – Erik Funkenbusch May 16 '12 at 03:51
  • Yes I agree to all of that. My goal tho is both. All of that and ease of swap out – CD Smith May 16 '12 at 03:54
  • I just don't think there's enough value to what you are trying to do to justify the effort. You're talking about a pretty large infrastructure to do something that gives you only marginal gains. If you want a plug-in style architecture, consider MEF. – Erik Funkenbusch May 16 '12 at 03:57
  • Ok, that's not one anyone has suggested to me. I'll definitely take a look, thanks for your input! In the meantime I'm hoping someone can point me to what I'm looking for in a fleshed out IoC/DI solution stack that I can get my hands on and learn from – CD Smith May 16 '12 at 04:00
  • Also, look at the last sentence in the answer you reference. Seeman says "Personally, I rarely find it worth that extra effort." All the extra effort to corral and manage assemblies brings its own stable of problems and issues. Nothing is a silver bullet, and software development is about trade-offs. Senior developers know what battles they can win in order to win the war as well (that is, ship a product) – Erik Funkenbusch May 16 '12 at 04:04
  • I totally agree with you. But I still would like to conquer this beast some day. There's nothing that I'm doing that will fail if I don't. Here is what I'm hearing. SOLID principles are what guide great software, unless you're doing something hard and complex in which case it's not worth it. To me, that's exactly when it's needed. You see what I mean? – CD Smith May 16 '12 at 04:09

2 Answers2

1

My Shuttle Wiki FOSS has some elements of what you are after:

http://shuttlewiki.codeplex.com/

Although not every concern is in its own proejct/assembly I have found that it is not worth the effort to tease them apart unless you are really going to use the relevant assembly somewhere else. That being said, it is still very easy to split them out as care has been taken to keep the concerns decoupled.

Scanned through some of the comments. My opinion is that no project structure or technique should be used to try and prevent or protect other developers from using certain classes. Junior developers have to learn the ropes at some stage and some quick code walkthroughs would pick up coding not consistent with what you are trying to achieve.

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • Thanks Eben, I'll have a look. I don't mean it as if it's the only reason I'm considering the architecture just to prevent that situation. My goal is simply to "get" composition root successfully understood, implemented and repeatable. I need to see how the solution should be structured to achieve the design even if I can't fully realize it with a massive solution. But my understanding of how to build the stack will be increased – CD Smith May 16 '12 at 04:24
  • I hope it helps. Composition root is just a fancy term indicating where the dependency wiring is invoked. You'll notice that even though I have a `DependencyWiring` class I invoke its methods in the `Application_Start` event. For a WinForms application it will be when the program starts up. In more complex scenarios I have various methods that perform different wiring since it isn't always necessary or relevant to wire *everything*. WinForms dependencies make no sense in a Windows Service or Web Site for instance. – Eben Roux May 16 '12 at 04:37
  • I agree with you 100%. Preventing junior developers from doing things is a terrible reason to do something this drastic. I can understand wanting to learn how to write an application in which there are no dependencies in the main app, but the premise of this question was to try to make it a project template that could be reused inplied an intention to use it for everything. I just don't find this kind of architecture beneficial enough to want to do that. – Erik Funkenbusch May 16 '12 at 15:49
  • Like I stated, it's not the only reason I'm looking for this. I have many reasons why I'm looking for a solution stack like this. Why is it so hard for someone to show me the intricacies of how an NTier solution can make use of an Ioc framework for DI? @EbenRoux is the only so far to propose such a stack. I see a lot of discussion about theory of IoC/DI and why but no real examples that make use of a stack of projects that implement IoC/DI. Single projects, sure, but I haven't written an app that uses 1 single project in 10 years. – CD Smith May 16 '12 at 17:17
  • I think you misunderstand about the stack as being a template.. I mean for it's parts to be reusable. Meaning, a stack that can make use of IoC/DI and work the way I want, will have assemblies that can be used in other systems. For example an assembly in the stack might be a LenderProductRequest entity which implements a ProductRequest interface... I could reuse that in several other solutions. But if I have no faith in the stack and how it implements DI because I can't get a wiring system to work then it's all for not. This is for learning, teaching, reuse, training other devs - multifaceted. – CD Smith May 16 '12 at 17:36
  • @CD: I agree. That is why the dependency injection should be abstracted also. Then you can wire using whatever you wish. There have been attempts at a 'standard' interface but it really is just *so* simple you can just roll your own --- which is what I did. – Eben Roux May 17 '12 at 06:35
  • @EbenRoux I saw that in your source code, you have the wiring interface returned to the startup and in your wiring concrete you configure not only your own classes but the controllers themselves. I think I need to wrap my head around why/how the controllers are configured by the IoC framework. I haven't had much time to really dig into it yet but just what I've had time to sort thru looks like the direction I'm trying to get to. I'd take it a layer or 2 further tho so I'd have to understand how to achieve deep DI from the top down into the bottom layer. Altogether tho this looks really good! – CD Smith May 17 '12 at 12:05
0

Take a look at mine: using repository pattern, ninject, entity framework 6, ...

https://github.com/mesuttalebi/NTierCSharpExample

mesut
  • 2,099
  • 3
  • 23
  • 35