I'm attempting to refactor a large codebase to use StructureMap. Does anyone know if there's a tool to quickly scan a codebase and report the number of volatile dependencies within classes? Sure, I could always search all files for the word "new", but this would also find non-volatile dependencies such as those used from BCL which are not material. I suppose that NDepend could, indirectly, provide some report on the degree of coupling which, is, indirectly, what I'm looking to eliminate. I'm just wondering if there was some tool that was specifically designed for the purpose of assisting with the migration towards the use of an IoC container.
I am not aware of anything like that. I think it would be quite hard to write a tool to identify volatile dependencies since they could be as diverse as file IO calls to database calls. Also, many developers draw the line between volatile and not in different places. Some would say System.Configuration is volatile, others would argue it is not...
Related
I am confused about this line
Aspect-Oriented Programming and Dependency Injection are very different concepts, but there are limited cases where they fit well together.
from this website
http://www.postsharp.net/blog/post/Aspect-Oriented-Programming-vs-Dependency-Injection
I understand the advantages of DI over AOP, but why aren't they used together more often? why are there only limited cases where they fit together? Is it because of the way AOP is compiled, that makes using both difficult?
How do you define "limited cases"? I myself always use AOP and DI together.
There are basically three ways to apply AOP, which are:
Using code weaving tools such as PostSharp.
Using dynamic interception tools such as Castle Dynamic Proxy.
Using decorators.
The use of DI with code weaving tools doesn't mix and match very well, and I think that's the reason that the Postsharp site states that "there are limited cases where they fit well together". One reason it doesn't mix and match is because Dependency Injection is about loose coupling, while code weaving hard couples your code and the aspects together at compile time. From a perspective of DI, code weaving becomes an anti-pattern. In section 11.2 of our book, Mark and I make this argument very clear. In summary we state:
The aim of DI is to manage Volatile Dependencies by introducing Seams into your application. Theis enables you to centralize the composition of your object graphs inside the Composition Root.
This is the complete opposite of hat you achieve when applying compile-time weaving: is causes Volatile Dependencies to be coupled to your code at compile-time. This makes it impossible to use proper DI techniques and to safely compose complete object graphs in the application's Composition Root. It's for this reason that we say that compile-time weaving is the opposite of DIāusing compile-time weaving on Volatile Dependencies is an anti-pattern. [page 355]
If you use dynamic interception, however, which means applying cross-cutting concerns at runtime by generating decorators on the fly it works great with DI and it is integrated easily with most DI libraries out there, and can be done as well when using Pure DI, which is something we demonstrate in section 11.1.
My personal preference is to use decorators. My systems are designed around a few well defined generic abstractions, and this allows me to apply cross-cutting concerns at almost all places that are important to my system. That leaves me in very rare cases with a few spots where decorators don't work very well, but this is almost always caused by design flaws. Either by my own limitations as a developer or by design flaws in the .NET framework or some other tool. One famous design flaw is the INotifyPropertyChanged interface. You might have guessed it, but in our book we describe this method in a lot of detail. We spend a complete chapter (10) on this topic.
In a large project that is using a DI framework (such as Ninject in my case), what options exist when implementing a new "service" to find out what other "services" are available to be used as dependencies. Before using DI I have noticed a tendency in our code base to get a reference to a "god" object that pretty much gave access to all the available functionality and then Visual Studio's IntelliSense would become very helpful to discover what all was available (obviously this approach was only possible because of poor architectural decisions of having such an object in the first place).
I can some possible answers and am interested what has worked for others:
You should know the overall system you are working in well enough
to know what other classes/services exist (for example, if I had
static classes I would just have to know that they exist to be able
to use them).
You maintain good external documentation of your
code base so all classes/services are understand by all developers
(this imposes a large documentation burden, it would seem to me).
Create an API to query the DI container (Ninject kernel) for a list
of all bindings to see what services are available (perhaps only
Singletons). This could also be done as part of the build system to
generate a document automatically upon each build that developers
could reference.
Has this ever been an issue for other developers?
Usually you don't want to see all services exist in a system and then choose one of them. You want to access a functionallity. Structure your classes with namespaces in a way so that it is obvious where to look for it.
E.g. If I want to know what collections are available in .NET I type System.Collections.Generic. and the IntelliSense gives me a list of options.
I tend to organise my codebase so that I have a central 'Interface' project to which all other projects have a reference. Then my Logger is available only through the ILogger interface, and the logging module can choose which concrete ILogger to provide. You should not be requesting concrete classes - this defeats the purpose of DI.
In general when you are implementing a new service you should already know what dependencies you need. If you don't know what you should use, ask someone who does. This is the equivalent to having adequate documentation - relying on intellisense will give you a very shallow idea of what you should take as a dependency. Instead you should consult either the documentation or someone who understands the area.
In the various programming projects I often work on, there are various levels of logic that I always feel have been done 1000 times before by others, but none the less I'm stuck doing them for the 1001st time.
For example, today I am coding tic tac toe, because I couldn't find source that had a reasonable interface.
The other day it was chess.
There are lots of classes like this, that are too specialized to be included in a library, but are none the less frequently written.
I am wondering if there is some kind of code sharing database or community that shares source for functions that might be reusable by others?
A single function is too small a unit to share and manage; everything basically boils down to copy-paste, which is evil. Separate libraries (in whatever form supported by your environment) represent a much more viable option. Hence, specialized repositories and general-purpose code hosting sites (GitHub, BitBucket, etc) is what you need.
Now, you can raraly find a truly specialized library out there, but you can always start one.
It depends on the language you are using. For example, Perl have CPAN: http://search.cpan.org.
XML seems to be the language of the day, but it's not type safe (without an external tool to detect problems) and you end up doing logic in XML. Why not just do it in the same language as the rest of the project. If it's java you could just build a config jar and put it on the classpath.
I must be missing something deep.
The main downside to configuration DI in code is that you force a recompilation in order to change your configuration. By using external files, reconfiguring becomes a runtime change. XML files also provide extra separation between your code and configuration, which many people value highly.
This can make it easier for testing, maintainability, updating on remote systems, etc. However, with many languages, you can use dynamic loading of the code in question and avoid some of the downsides, in which case the advantages diminish.
Martin Fowler covered this decision pretty well here:
http://martinfowler.com/articles/injection.html
Avoiding the urge to plagiarize... just go read the section "Code or configuration files".
There's nothing intrinsically wrong with doing the configuration in code, it's just that the tendency is to use XML to provide some separation.
There's a widespread belief that somehow having your configuration in XML protects you from having to rebuild after a change. The reality in my experience is that you need to repackage and redeploy the application to deliver the changed XML files (in the case of web development anyway), so you could just as easily change some Java "configuration" files instead. Yo could just drop the XML files onto the web server and refresh, but in the environment I work, audit would have a fit if we did.
The main thing that using XML configuration achieves in my opinion is forcing developers to think about dependency injection and separation of concerns. in Spring (amongst others), it also provides a convenient hook to hang your AOP proxies and suchlike. Both of these can be achieved in Java configuration, it is just less obvious where the lines are drawn and the tendency may be to reintroduce direct dependencies and spaghetti code.
For information, there is a Spring project to allow you to do the configuration in code.
The Spring Java Configuration project (JavaConfig for short) provides a type-safe, pure-Java option for configuring the Spring IoC container. While XML is a widely-used configuration approach, Spring's versatility and metadata-based internal handling of bean definitions means alternatives to XML config are easy to implement.
In my experience, close communication between the development team and the infrastructure team can be fostered by releasing frequently. The more you release, the more you actually know what the variability between your environments are. This also allows you to remove unnecessary configurability.
A corollary to conway's law applies here - your config files will resemble the variety of environments your app is deployed to (planned or actual).
When I have a team deploying internal applications, I tend to drive towards config in code for all architectural concerns (connection pools, etc), and config in files for all environmental config (usernames, connection strings, ip addresses). If there different architectural concerns across different environments, then I'll encapsulate those into one class, and make that classname part of the config files - e.g.
container.config=FastInMemoryConfigurationForTesting
container.config=ProductionSizedConfiguration
Each one of these will use some common configuration, but will override/replace those parts of the architecture that need replacing.
This is not always appropriate however. There are several things that will affect your choice:
1) how long it takes after releasing a new drop before it is deployed successfully in each production environment and you receive feedback on that environment (cycle time)
2) The variability in deployed environments
3) The accuracy of feedback garnered from the production environments.
So, when you have a customer who distributes your app to their dev teams for deployment, you are going to have to make your app much more configurable than if you push it live yourself. You could still rely on config in code, but that requires the target audience to understand your code. If you use a common configuration approach (e.g. Spring), you make it easier for the end users to adapt and workaround issues in their production.
But a rubric is: configurability is a substitute for communication.
XML is not meant to have logic, and it's far from being a programming language.
XML is used to store DATA in a way easy to understand and modify.
Has you say, it's often used to store definitions, not business logic.
You mentioned Spring in a comment to your question, so that suggests you may be interested in the fact that Spring 3 lets you express your application contexts in Java rather XML.
It's a bit of a brain-bender, but the definition of your beans, and their inter-dependencies, can be done in Java. It still keeps a clean separation between configuration and logic, but the line becomes that bit more blurred.
XML is mostly a data (noun) format. Code is mostly a processing (verb) format. From the design perspective, it makes sense to have your configuration in XML if it's mostly nouns (addresses, value settings, etc) and code if it's mostly verbs (processing flags, handler configurations, etc).
Its bad because it makes testing harder.
If you're writing code and using methods like getApplicationContext() to obtain the dependencies, you're throwing away some of the benefits of dependency injection.
When your objects and services don't need to know how to create or acquire the resources on which they depend, they're more loosely coupled to those dependencies.
Loose coupling means easier unit testing. Its hard to get something into a junit if you need to instantiate all its dependencies. When a class omits assumptions about its dependencies, its easy to use mock objects in place of real ones for the purpose of testing.
Also, if you can resist the urge to use getApplicationContext() and other code based DI techniques, then you can (sometimes) rely on spring autowiring which means means even less configuration work. Configuration work whether in code or in XML is tedious, right?
I believe that most IoC containers allow you to wire dependencies with XML configuration file. What are cons and pros for using configuration file vs. registering dependencies in code?
These pros and cons are based on my work with spring. It may be slightly different for other containers.
XML
pro
flexible
more powerful than annotations in some areas
very explicit modelling of the dependencies of your classes
con
verbose
difficulties with refactoring
switching between several files
Annotations
pro
less file switching
auto configuration for simple wirings
less verbose than xml
con
more deployment specific data in your code (usually you can override this with xml configs)
xml is almopst(?) always needed, at least to set up the annonation based config
annotation magic may lead to confusion when searching for the class that is used as dependency
Code
pro
Can take advantage of strongly-typed languages (e.g. C#, Java)
Some compile-time checking (can't statically check dependencies, though)
Can take advantage of DSLs (e.g. Binsor, Fluent interfaces)
Less verbose than XML (e.g. you don't need to always specify the whole assembly qualified name (when talking .net))
con
wiring via code may lead to complex wirings
hard dependencies to IOC container in the codebase
I am using a mix of XML+Annotation. Some things especially regarding database access are always configured via xml, while things like the controllers or services are mostly configured via annotations in the code.
[EDIT: I have borrowed Mauschs code PROs]
XML pros:
Can change wiring and parameters without recompiling. Sometimes this is nice to have when switching environments (e.g. you can switch a fake email sender used in dev to the real email sender in production)
Code pros:
Can take advantage of strongly-typed languages (e.g. C#, Java)
Some compile-time checking (can't statically check dependencies, though)
Refactorable using regular refactoring tools.
Can take advantage of DSLs (e.g. Binsor, Fluent interfaces)
Less verbose than XML (e.g. you don't need to always specify the whole assembly qualified name (when talking .net))
I concur. I have found ioc containers to give me very little, however they can very easily make it harder to do something. I can solve most of the problems I face just by using my programming language of choice, which have allways turned out to be simpler easier to maintain and easier to navigate.
I'm assuming that by "registering dependencies in code" you mean "use new".
'new' is an extraordinarily powerful dependency injection framework. It allows you to "inject" your "dependencies" at the time of object creation - meaning no forgotten parameters, or half-constructed objects.
The other major potential benefit is that when you use refactoring tools (say in Resharper, or IntelliJ), the calls to new change too
Otherwise you can use some XML nonsense and refactor with XSL.