Archive for April, 2011

What's new in Windsor 3: Container debugger diagnostics improvements

Monday, April 25th, 2011

As we're near­ing the release date of Cas­tle Wind­sor 3.0 (code­name Wawel) I will be blog­ging about some of the new fea­tures and improve­ments intro­duced in the new version.

In the pre­vi­ous post I intro­duced one new diag­nos­tic, and in this post we’ll explore other improve­ments in this area.

Overview

In the screen­shot below (and all other) the upper win­dow is Wind­sor 2.5, lower win­dow is Wind­sor 3. All screen­shots were taken run­ning one of open source applications.

image

As you can see there are some addi­tional diag­nos­tics present in the new ver­sion. Alto­gether the num­ber rose from 4 in pre­vi­ous ver­sion to 7 in Wawel (you’re not see­ing all of them in the screen­shots above because some of them only acti­vate if they have some­thing to show). The new ones are:

  • Default com­po­nent per ser­vice – if you have mul­ti­ple com­po­nents expos­ing one ser­vice this will show you which one of them is the default (that is which one will be used pri­mar­ily to sat­isfy depen­den­cies of that type).
  • Poten­tial Ser­vice Loca­tor usage was dis­cussed pre­vi­ously

Objects tracked by release policy

image

This one is pretty self explana­tory. It shows you all objects tracked by release pol­icy in your con­tainer, grouped by com­po­nent. Do not under­es­ti­mate the value of it. This is a fan­tas­tic tool for locat­ing objects with mis­man­aged life­time (in other words – objects that should have been released but weren’t). If you see a num­ber next to any of your com­po­nents is sus­pi­ciously high or ris­ing you may have just dis­cov­ered a flaw in life­time man­age­ment in your app.

It is worth not­ing that there were some sig­nif­i­cant changes around release poli­cies in Wind­sor 3 and what is tracked by the pol­icy has changed as well. Those changes will be cov­ered in a future post.

Com­po­nents view

Most of the debug­ger views deals with show­ing com­po­nents and there are some improve­ments in this area. Let’s go through most notable of them.

image

  • Top level view no longer shows a sequence num­ber as “Name”. The num­ber had no real mean­ing and we’re show­ing instead a much more impor­tant infor­ma­tion – lifestyle of the component.
  • If lifestyle was not set explic­itly (and Wind­sor falls back to its default for it) there will be an addi­tional star (*) next to the lifestyle, like the “Now” com­po­nent on the screenshot.
  • How we dis­play the com­po­nent was also greatly sim­pli­fied to make it much more readable.
    • We’re not show­ing the name Windsor’s using for the com­po­nent, unless you explic­itly set it. Oth­er­wise it’s just noise.
    • We’re show­ing C#-ified names of types so that they are much eas­ier to read.
    • To show open generic ser­vices we put dots (·) around generic para­me­ters, so that they stand out from nor­mal types.

Sev­eral other more minor improve­ments were intro­duced as well, but I won’t go into too much detail here.

Access­ing diag­nos­tics in code

Ever since the fea­ture was intro­duced there were requests to pro­vide pro­gram­ma­ble access to those diag­nos­tics. It is now pos­si­ble. Thanks to changes in inter­nal infra­struc­ture you can use new IDi­ag­nos­tic<> inter­face (and it’s subin­ter­faces) to write code like this:

var host = Container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey) as IDiagnosticsHost;
var diagnostic = host.GetDiagnostic<IUsingContainerAsServiceLocatorDiagnostic>();
var serviceLocators = diagnostic.Inspect();
Assert.IsEmpty(serviceLocators);

I hope you’ll find all of those improve­ments useful.

What's new in Windsor 3: Service Locator usage detection

Sunday, April 24th, 2011

As we're near­ing the release date of Cas­tle Wind­sor 3.0 (code­name Wawel) I will be blog­ging about some of the new fea­tures and improve­ments intro­duced in the new version.

One of the fea­tures that were intro­duced in cur­rent ver­sion 2.5 was sup­port for debug­ger diag­nos­tic views in Windsor.

In Wawel one of the improve­ments is addi­tion of a new diag­nos­tic — detec­tion of cases where the con­tainer is being used as Ser­vice Loca­tor. For those unfa­mil­iar with what Ser­vice Loca­tor is, it's an approach that breaks the basic rule of Inver­sion of Con­trol, by explic­itly call­ing out to the con­tainer from within application.

Here's where I tell you Ser­vice Loca­tor is bad

I spent last two days read­ing through the Stack­Over­flow archive of IoC related ques­tions and one of the most com­mon sources of prob­lems is that con­tainer is being used as Ser­vice Locator.

I wrote why Ser­vice Loca­tor (par­tic­u­larly when imple­mented via IoC con­tainer) is a bad idea on few occa­sions (for exam­ple here). Also Mark has a good overview of draw­backs of this approach so I won't rehash it again.

Good news is — even if some­one from your team starts using the con­tainer as Ser­vice Loca­tor, Wind­sor will now help you detect those cases.

Here's where I give you an example

Take a look at the fol­low­ing class:

[Singleton]
public class ComponentFactory
{
    private readonly IKernel kernel;

    public ComponentFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public object Create(String name)
    {
        return kernel.Resolve<object>(name);
    }
}

It is part of the appli­ca­tion layer (and not infra­struc­ture layer) and as such it should not be aware of the con­tainer, yet it depends on IKer­nel. Also quick look at its Cre­ate method is enough to see that it most likely is passed around through­out the appli­ca­tion and used to pull com­po­nents from the con­tainer with­out giv­ing it much thought, which as you're surely guess­ing by now is a recipe for trouble.

Here's where I show you how it looks

If you nav­i­gate in debug mode to a con­tainer instance where com­po­nents like the one described above exists a new entry in the debug­ger view will appear list­ing those components.

sl-detection

Here's where I tell you how it works

Wind­sor doesn't have the whole pic­ture of your appli­ca­tion, so it can only detect a sub­set of cases of Ser­vice Loca­tor usage. In par­tic­u­lar it is unable to detect the case when a Ser­vice Loca­tor is built com­pletely on top of the con­tainer as com­monly found, where con­tainer is assigned to a pub­lic field of a sta­tic class and accessed through that field.

Since Wind­sor only knows about the com­po­nents you reg­is­ter with it, it looks for com­po­nents that depend on the con­tainer and are not extend­ing infra­struc­ture of the con­tainer itself (like for exam­ple Inter­cep­tors are). All such com­po­nents are flagged as poten­tial ser­vice loca­tor and pre­sented to you.

I hope you'll find this fea­ture useful.

Here's where you tell me what you think