Seems like everyone is moving towards IoC containers. I've tried to "grok" it for a while, and as much as I don't want to be the one driver to go the wrong way on the highway, it still doesn't pass the test of common sense to me. Let me explain, and please correct/enlighten me if my arguments are flawed:
My understanding: IoC containers are supposed to make your life easier when combining different components. This is done through either a) constructor injection, b) setter injection and c) interface injection. These are then "wired up" programmatically or in a file that's read by the container. Components then get summoned by name and then cast manually whenever needed.
What I don't get:
EDIT: (Better phrasing)
Why use an opaque container that's not idiomatic to the language, when you can "wire up" the application in (imho) a much clearer way if the components were properly designed (using IoC patterns, loose-coupling)? How does this "managed code" gain non-trivial functionality? (I've heard some mentions to life-cycle management, but I don't necessarily understand how this is any better/faster than do-it-yourself.)
ORIGINAL:
Why go to all the lengths of storing the components in a container, "wiring them up" in ways that aren't idiomatic to the language, using things equivalent to "goto labels" when you call up components by name, and then losing many of the safety benefits of a statically-typed language by manual casting, when you'd get the equivalent functionality by not doing it, and instead using all the cool features of abstraction given by modern OO languages, e.g. programming to an interface? I mean, the parts that actually need to use the component at hand have to know they are using it in any case, and here you'd be doing the "wiring" using the most natural, idiomatic way - programming!
There are certainly people who think that DI Containers add no benefit, and the question is valid. If you look at it purely from an object composition angle, the benefit of a container may seem negligible. Any third party can connect loosely coupled components.
However, once you move beyond toy scenarios you should realize that the third party that connects collaborators must take on more that the simple responsibility of composition. There may also be decommissioning concerns to prevent resource leaks. As the composer is the only party that knows whether a given instance was shared or private, it must also take on the role of doing lifetime management.
When you start combining various instance scopes, using a combination of shared and private services, and perhaps even scoping some services to a particular context (such as a web request), things become complex. It's certainly possible to write all that code with poor man's DI, but it doesn't add any business value - it's pure infrastructure.
Such infrastructure code constitutes a Generic Subdomain, so it's very natural to create a reusable library to address such concerns. That's exactly what a DI Container is.
BTW, most containers I know don't use names to wire themselves - they use Auto-wiring, which combines the static information from Constructor Injection with the container's configuration of mappings from interfaces to concrete classes. In short, containers natively understand those patterns.
A DI Container is not required for DI - it's just damned helpful.
A more detailed treatment can be found in the article When to use a DI Container.
I'm sure there's a lot to be said on the subject, and hopefully I'll edit this answer to add more later (and hopefully more people will add more answers and insights), but just a couple quick points to your post...
Using an IoC container is a subset of inversion of control, not the whole thing. You can use inversion of control as a design construct without relying on an IoC container framework. At its simplest, inversion of control can be stated in this context as "supply, don't instantiate." As long as your objects aren't internally depending on implementations of other objects, and are instead requiring that instantiated implementations be supplied to them, then you're using inversion of control. Even if you're not using an IoC container framework.
To your point on programming to an interface... I'm not sure what your experience with IoC containers has been (my personal favorite is StructureMap), but you definitely program to an interface with IoC. The whole idea, at least in how I've used it, is that you separate your interfaces (your types) from your implementations (your injected classes). The code which relies on the interfaces is programmed only to those, and the implementations of those interfaces are injected when needed.
For example, you can have an IFooRepository which returns from a data store instances of type Foo. All of your code which needs those instances gets them from a supplied object of type IFooRepository. Elsewhere, you create an implementation of FooRepository and configure your IoC to supply that anywhere an IFooRepository is needed. This implementation can get them from a database, from an XML file, from an external service, etc. Doesn't matter where. That control has been inverted. Your code which uses objects of type Foo doesn't care where they come from.
The obvious benefit is that you can swap out that implementation any time you want. You can replace it with a test version, change versions based on environment, etc. But keep in mind that you also don't need to have such a 1-to-1 ratio of interfaces to implementations at any given time.
For example, I once used a code generating tool at a previous job which spit out tons and tons of DAL code into a single class. Breaking it apart would have been a pain, but what wasn't much of a pain was to configure it to spit it all out in specific method/property names. So I wrote a bunch of interfaces for my repositories and generated this one class which implemented all of them. For that generated class, it was ugly. But the rest of my application didn't care because it saw each interface as its own type. The IoC container just supplied that same class for each one.
We were able to get up and running quickly with this and nobody was waiting on the DAL development. While we continued to work in the domain code which used the interfaces, a junior dev was tasked with creating better implementations. Those implementations were later swapped in, all was well.
As I mentioned earlier, this can all be accomplished without an IoC container framework. It's the pattern itself that's important, really.
First of all what is IOC? It means that responsibility of creating the dependent object is taken away from the main object and delegated to third party framework. I always use spring as my IOC framework and it bring tons of benefit to the table.
Promotes coding to interface and decoupling - The key benefit is that IOC promotes and makes decoupling very easy. You can always inject an interface in your main object and then use the interface methods to perform tasks. The main object does not need to know which dependent object is assigned to the interface. When you want to use a different class as dependency all you need is to swap the old class with a new one in the config file without a single line of code change. Now you can argue that this can be done in the code using various interface design patterns. But IOC framework makes its walk in a park. So even as a newbie you become expert in levering various interface design patterns like bridge, factory etc.
Clean code - As most of object creation and object life-cycle operations are delegated to IOC container you saved from the writing broiler point repetitive code. So you have a cleaner, smaller and more understandable code.
Unit testing - IOC makes unit testing easy. Since you are left with decoupled code you can easily test the decoupled code in isolation. Also you can easily inject dependencies in your test cases and see how different component interacts.
Property Configurators - Almost all the applications have some properties file where they store application specific static properties. Now to access those properties developers need to write wrappers which will read and parse the properties file and store the properties in format that application can access. Now all the IOC frameworks provide a way of injecting static properties/values in specific class. So this again becomes walk in the park.
These are some of the points I can think right away I am sure there are more.
Related
I read a lot of ViewModel derived from AndroidViewModel, which then requires of course an application reference.
class SomeViewModel(application: Application) : AndroidViewModel(application)
But why would one do this? It hurts me to see application handed over to ViewModel. What would be an acceptable use case for this?
If there is any reason to use AndroidViewModel, can one not derive from ViewModel + use dagger2 for the application inject?
Not all codebases are created equal. AndroidViewModel can be a useful tool for incremental refactoring in "legacy" codebases that don't have many abstractions or layering in place (read: Activity/Fragment god objects).
As a bridge from a "legacy" codebase, it makes sense to use it in this situation.
But why would one do this? It hurts me to see application handed over to ViewModel. What would be an acceptable use case for this?
The use case for AndroidViewModel is for accessing the Application. In a "legacy" codebase, it's relatively safe to move "Context/Application-dependent code" out of Activities and Fragments without requiring a risky refactor. Accessing Application in the view model will be necessary in that scenario.
If there is any reason to use AndroidViewModel, can one not derive from ViewModel + use dagger2 for the application inject?
If you're not injecting anything else, then at best it's a convenient way to get an Application reference without having to type cast or use any DI at all.
If you're injecting other members, be it with a DI framework or ViewModelFactory, it's a matter of preference.
If you're injecting a ViewModel directly into your Activity/Fragment, you're losing the benefits the platform is providing you with. You'll have to manually scope the lifecycle of your VM and manually clear your VM for your UI's lifecycle unless you also mess around with ViewModelStores or whatever other components are involved in retention. At that point, it's a view model by name only.
Because it requires an application reference, it can provide Context which can be useful (e.g: for a system service).
See - AndroidViewModel vs ViewModel
I am a newcomer to C# / .Net / Prism / WPF / DevExpress and started to work on a big project in my company. As I am starting a bit late in the project, a lot of code was already produced and I stumble upon code like this very often:
public class AboutWindowViewModel : BindableBase
{
public AboutWindowViewModel(IUnityContainer container)
{
...
What I find "special" here is the dependence of the view model in the container. In the codebase I am currently looking at, it seems to be the "pattern". Every class gets a dependence in the IUnityContainer and then the dependencies are resolved manually with e.g.
container.ResolveEx<...>(...);
I am used to work with DI frameworks in other languages, so that example was just a non-sense to me because it goes against the definition of a DI framework and the problems it is meant to solve. For example, I tried to make up some code to test one of those view models and it turned out to be a nightmare.
Now, I addressed that concern to the developpers of my company and they answered me the following:
Prism recommendation is to resolve services using containers as they are needed.
Therefore, they resolve them all the time with the IUnityContainer.ResolveEx method.
My question is: is that really the recommended way to build up software with Prism??? If not, do you know where I can find documentation that clearly addresses that point with examples?
is that really the recommended way to build up software with Prism???
Not at all, in it's an anti-pattern.
Prism recommendation is to resolve services using containers as they are needed.
Not really just Prism, but more generally, the recommendation is to let the container resolve the dependencies. Of course, this can be done by calling Resolve manually, but in doing that one defeats all the benefits expected from dependency injection.
Rather, you want to list the dependencies as constructor parameters and let the container fill them. Your code does not need to depend on the container, except for the very entry-point ("resolution root"). The application should only ever contain a single Resolve statement that resolves the first instance.
Here's where Prism comes into play: in your PrismApplication.RegisterTypes and IModule.RegisterTypes, you configure your container. You tell it which type should implement which interface. Later on, when view models are needed, Prism (the ViewModelLocator to be precise) uses the container to resolve the view models, thereby resolving all the dependencies. There's no reason to make any class depend on the container, in fact, Prism doesn't register anything for IContainerRegistry in the first place.
Keep in mind that the container can not only inject singleton services, but also transient instances or factories. And if you need parametrized factories, you can always manually create and register complex factories.
On a side-note, I, personally, would be hesitant to work for a client with a code-base like this, as it's an obvious proof that their developers have no idea what they're doing.
Previously I asked this question and on a answer I got this comment:
This works, however injecting the container to a part, as far as I know, is not a "normal" use-case of MEF.
In my web app I have a few repositories that, of course, retrieve entities from the DB. To make them as loosely coupled as possible I'm making them return interfaces (eg IUser, IBill, IBlaBlaBla...) and the repository project only references the library project (that contains the interfaces). I use MEF composition capabilities to tie it all up...
Since the repository must have a concrete object to fill with info it got from the DB and the only the Container is aware of which concrete class maps to a specific interface I think that the repository MUST have reference to the container so it can call the "Resolve()", get a new instance and do his job, but that apparently is a mistake.
Can anyone tell me why and what approach would be better?
PS: I don't know if it's relevant but I'm using DDD...
I think the flaw in your design that lead to this problem is the use of interfaces to hide entities behind. Since entities are your core concept in your domain, there should be no use in hiding them behind an abstraction. Let's put it differently: do you ever have a different implementation of IUser?
In other words, ditch the IUser, IBill, etc. interface and let your repositories and business commands depend directly on your aggregate entities.
Jeffrey Palermo pioneered the onion architecture, which I have found a good approach.
http://www.headspring.com/jeffrey/onion-architecture-part-4-after-four-years/
However his statement "Inner layers define interfaces. Outer layers implement interfaces" seems to contradict IoC, if my understanding is correct, which states that Consumer define interface and providers implement it, i.e. the control lies with the consumer not the provider.
This principle makes sense to me, since, imagine you are writing a UI, this principle means you can get on with creating your UI without knowing anything about the services you are going to call since you are in charge of defining the interface that exposes all the functionality your will need.
So to that end Jeffreys statement seems a contradiction and confuses me about where to put contract(interface definitions), because it seems to imply that:
Domain Layer
MyEntity
IMyService
Service
MyEntityService : IMyService
Since there is no layer beneath Domain, where do I put IMyEntity. Also it means I cannot create a Presentation project until Domain exists and has defined IMyService.
As I side note, where do I place IMyEntityRepository and MyEntityRepository ? Since service relies on IMyEntityRepository and MyEntityRepository relies on IMyEntity
So, where to begin? :-)
Let’s start with the real role of an IOC. According to Wikipedia,
Inversion Of Control is a programming technique in which object
coupling is bound at run time by an assembler object and is typically
not known at compile time.
In your case, your UI will manipulate services interfaces without knowing the service implementation that will be bound at run time. It’s not up to the consumer to define those service interfaces; they will be defined in the application core of your Onion architecture, but we’ll see that later.
"Inner layers define interfaces. Outer layers implement interfaces", that’s how the Onion Architecture is designed, but do not forget that the outermost layer is the IOC! It’s up to the IOC to bind interfaces with the right implementations at run time!
You’re right saying that your UI won’t work without having at least one implementation available for the interfaces you will manipulate. But in this case, if for any reason you need to build your UI first, consider using a mocking framework!
Your last question is about where you need to place your IMyEntityRepository and MyEntityRepository classes. Well, that’s the easy part ;-) IMyEntityRepository definitely needs to be placed within your Application core. All your entities, service interfaces, repository interfaces and whatever interfaces need to be at the same place. MyEntityRepository implementation should be placed somewhere in your infrastructure layer as his role will be mainly to deal with getting data out of the DB.
Hope that helps!
I have worked with Jeffrey for many years, and I would say that IoC is integral to making Onion Architecture possible. Interfaces for external dependencies are defined in projects with few (if any) dependencies (in other words, projects at the "center" of the onion). Classes that implement those interfaces that depend on external dependencies are located in projects at the edge / on the surface of the onion. IoC containers, then, are needed to "hook up" the class implementations on the edge of the onion to interfaces at the core of the onion at run-time.
We've implemented Onion on my project and it's conceptually pretty simple.
Create a project that contains only interfaces and POCO's, we'll call this Contract for now
Create one or more projects that contains the implementations of your interfaces and all your 3rd party things like NHibernate mappings, we'll call this Implementation(s)
Add a direct reference to Contract from projects that need to use this functionality but don't add a reference to Implementation from these projects
In your composite root (application entry point) projects do two things (1) as part of the build copy the latest version of implementation to a configured location (we use AppSettings for the configuration but there are a lot of options here) (2) have your container scan the configured location for your Implementation Dll(s)
This approach allows you to only rely on Contract and the idea is that you can switch Implementation so if you want to move to Entity Framework or something else in the future you only have to reimplement Implementation using that framework.
We also copy the NHibernate DLLs to the configured scanning location and this allows us to make the architecture defensive so that it is difficult to not follow the it because NHibernate is only available where it should be used.
The interfaces in the onion architecture are the ones that the layer depends on (i.e. consumes), whose implementation indeed is provided by the outer layer.
More specifically, the architecture itself does not say you have to abstract the business logic behind interfaces (which you should probably do anyway, in respect of the dependency inversion principle, but that's another story). What is says is that the dependencies of the layer should be modeled as interfaces so implementations can be provided by the outer layer.
The best example is infrastructure code, and particularly data access. Your business logic needs to load and store data, so it defines an interface that it'll consume. The outer layer will provide an implementation using NHibernate or EF or whatever.
Actually, the low-level layers (from the DIP; i.e. the data access and other commodities) are on the outermost layers of the onion, while the high-level layers (i.e. the business logic) are closer to the center.
See also http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html which replaces the domain, business logic and more business logic terms with entities, use cases and interface adapters which IMO are easier to reason about. The farther you go from the center, the most specific you are to what the user sees and use; the closer to the center the more generic; at the center are those things that are transverse to your enterprise, then the use cases which are specific to your app more don't dictate how they'll be used or in which environment (which DB, which UI, etc.), then you'll make adapters between your use-cases and your technical framework (ASP.NET MVC, WCF, WPF –in a non-web scenario–, EF, NHibernate, etc.)
I'm starting to use MVVM Light version 4,and i can't understand:
Why should i use DataService and IDataService?
Should i create a dataservice for any class in model?
First of all - as usual - in MVVM you do not have to do something, it is a recommendation or best practice. In general you are free to code the data access into your view model - and to do so might be a good practice for small projects or prototypical implementations.
However, you should consider that this also has some drawbacks. The reason for implementing a data service is that this component is reusable and even might be usable in other scenarios like an MVC application. Furthermore, it separates out the concern of getting model from a data store.
The reason for implementing an IDataService is that you can exchange the implementation when you need to, e.g. for supplying design time data. When you need this, you also have to consider the inversion of control pattern that heavily relies on interfaces. In this case also a IOC container might be interesting, although not necessary.
But, first of all the above are recommendations, patterns, design guidelines, and best practices that give you the freedom to design an application that best fits your requirements.
Edit: size of the data service
The design and scope of your data service depends on your application and it's requirements. It can range from a single data service for all you models to one data service per model. Furthermore, the design of you data service interfaces may be a separate decision. One service class can implement several service interfaces, thus allowing for hiding certain aspects (methods) of the implementation from the user.
When designing a data service you should look into the unit of work and repository patterns. There are several sample implementations around.
If you just need a very simple unit of work pattern that is based on a single query you can have a look at my blog, where I wrote about turning an IQueryable into a unit of work pattern. However, this fits only very simple cases, generally a complete implementation with a repository and a proper unit of work item is more advisably.