5.31.2010

Interface Segregation Principle in practice

I am working with some other team members integrating components to be consumed by different controls. For example someone could use a grid and then opt in to have sorting or filtering etc. It is a rather weird system but was decided upon before I arrived.

Anyway, I am currently looking to implement an adapter for the formatting component. When I looked at the interface, ISP immediately jumped out at me. So I thought, why not do a blog post about identifying the problem and delivering the solution.

Interface Segregation Principle

The Interface Segregation Principle states that clients should not be forced to implement interfaces they don’t use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one submodule. - http://www.oodesign.com/interface-segregation-principle.html

So instead of one large interface we should have many smaller interfaces with grouped behavior.

When we see an interface like this, the violation of ISP should be readily apparent. (warning.. be prepared to scroll…..)

/// <summary>
    /// An interface defining the contract for anything that has columns that can be formatted.
    /// </summary>
    public interface IColumnFormattingAdapter
    {
        #region Methods

        /// <summary>
        /// Hides the column.
        /// </summary>
        void HideColumn();

        /// <summary>
        /// Bests the fit header.
        /// </summary>
        void BestFitHeader();

        /// <summary>
        /// Bests the fit column.
        /// </summary>
        void BestFitColumn();

        /// <summary>
        /// Bests the fit header column.
        /// </summary>
        void BestFitHeaderColumn();

        /// <summary>
        /// Bests the fit all columns/headers.
        /// </summary>
        void BestFitAllHeaderColumns();

        /// <summary>
        /// Formats the column.
        /// </summary>
        void FormatColumn();

        /// <summary>
        /// Formats all columns.
        /// </summary>
        void FormatAllColumns();

        /// <summary>
        /// Shows the advanced formatting.
        /// </summary>
        void ShowAdvancedFormatting();
        
        /// <summary>
        /// Shows the advanced report formatting.
        /// </summary>
        void ShowAdvancedReportFormatting();

        /// <summary>
        /// Chooses the column.
        /// </summary>
        void ChooseColumn();

        #endregion

        #region Feature Support

        /// <summary>
        /// Whether or not the adapter supports hiding of columns
        /// </summary>
        Boolean AllowHideColumn { get; }

        /// <summary>
        /// Whether or not the adapter supports best fit based on the header text
        /// </summary>
        Boolean AllowBestFitHeader { get; }

        /// <summary>
        /// Whether or not the adapter supports best fit based on the column contents
        /// </summary>
        Boolean AllowBestFitColumn { get; }

        /// <summary>
        /// Whether or not the adapter supports best fit based on the longer of header text and column contents
        /// </summary>
        Boolean AllowBestFitHeaderColumn { get; }

        /// <summary>
        /// Whether or not the adapter supports best fit on all columns based on the longer of header text and column contents
        /// </summary>
        Boolean AllowBestFitAllHeaderColumns { get; }

        /// <summary>
        /// Whether or not the adapter supports formatting of a column
        /// </summary>
        Boolean AllowFormatColumn { get; }

        /// <summary>
        /// Whether or not the adapter supports formatting of all columns
        /// </summary>
        Boolean AllowFormatAllColumns { get; }

        /// <summary>
        /// Whether or not the adapter supports advanced conditional formatting
        /// </summary>
        Boolean AllowAdvancedFormatting { get; }

        /// <summary>
        /// Whether or not the adapter supports advanced report property formatting
        /// </summary>
        Boolean AllowAdvancedReportFormatting { get; }

        /// <summary>
        /// Whether or not the adapter supports choosing columns
        /// </summary>
        Boolean AllowChooseColumn { get; }

        #endregion
    }

Identifying ISP Violation

The first characteristic that the interface violates ISP is the sheer size. This interface weighs in at 117 lines. Granted there are comments, etc but it is still rather large.

The second characteristic that the interface violates ISP (and the biggest eye sore) is all the Allow properties. That should make you stop and scratch your head.

Fixing the interface

Let’s simplify the bad interface and then learn how to fix it.

/// <summary>
/// An interface defining the contract for anything that has columns that can be formatted.
/// </summary>
public interface IBadColumnFormattingAdapter
{
    /// <summary>
    /// Hides the column.
    /// </summary>
    void HideColumn();

    /// <summary>
    /// Chooses the column.
    /// </summary>
    void ChooseColumn();
   
    /// <summary>
    /// Whether or not the adapter supports hiding of columns
    /// </summary>
    Boolean AllowHideColumn { get; }

    /// <summary>
    /// Whether or not the adapter supports choosing columns
    /// </summary>
    Boolean AllowChooseColumn { get; }
}

So in this scenario we can hide a column and then choose a column. Instead of having a large interface for these two behaviors, we should package the behaviors into separate interfaces.

 /// <summary>
    ///Interface for supporting Hide Column feature
 /// </summary>
 public interface IHideColumn
 {
     /// <summary>
        ///Hides the column.
     /// </summary>
     void HideColumn();
 }

 /// <summary>
    ///Interface for supporting Choose Column feature
 /// </summary>
 public interface IChooseColumn
 {
     /// <summary>
        ///Chooses the column.
     /// </summary>
     void ChooseColumn();
 }

Now our functionality is encapsulated into behavior centric interfaces. Our adapters can then opt in to provide the functionality, and we don’t have the superfluous Allow properties.

5.28.2010

Structure Map 2.6 Constructing the Concrete Type

Basic Use with Func<T>

Ryan yet again was asking for how to do another crazy thing with Structure Map. :)

He wanted to know if there was a way to control the construction of a concrete type. Well.. he didn’t put it that way but it is what he wanted to know.

Besides the regular For<I>().Use<C>()… we have the ability to construct the concrete type ourselves with a simple action.

To demo this I have a Foo class that accepts a string in the constructor.

class Foo : IFoo
{
    public Foo(string message)
    {
        Message = message;
    }

    public string Message { get; set; }
}

We want to pass in the message explicitly so we configure our container and tell it how to provide the concrete implementation.

_container = new Container();
_container.Configure(x => x.For<IFoo>().Use(() => new Foo("Hello")));

And the tests to verify it works :

[Test]
public void IFoo_should_resolve_to_Foo()
{
    var foo = _container.GetInstance<IFoo>();

    foo.ShouldBeType<Foo>();            
}

[Test]
public void message_should_be_set_during_construction()
{
    var foo = _container.GetInstance<IFoo>();
    
    foo.Message.ShouldBe("Hello");
}

Using Func<IContext, T>

There are other scenarios where not only do you want more control on a concrete types construction, but also need to resolve other dependencies. SM also allows you to specify a Func<IContext,T> where the IContext allows you to resolve classes from the container.

So if we have a scenario with an IBar and an IFoo:

class Bar : IBar
{
    public IFoo Foo { get; set; }
}

class Foo : IFoo
{
}

interface IBar
{
    IFoo Foo { get; }
}

interface IFoo
{
}

We can use the Func<IContext,T> similar to how we used the Func<T>.

_container = new Container();

_container.Configure(x =>
{
    x.For<IFoo>().Use<Foo>();
    x.For<IBar>().Use(c =>
                          {
                              var bar = new Bar();
                              bar.Foo = c.GetInstance<IFoo>();
                              return bar;
                          });
});

And naturally our test to verify it works:

[Test]
public void should_set_foo_property_on_bar()
{
    var bar = _container.GetInstance<IBar>();

    bar.Foo.ShouldBeType<Foo>();
}

So that was a brief introduction into using Funcs to provide the concrete implementation of an interface for Structure Map.

All the Learning Structure Map code can be found in my Learning solution on Git Hub : http://github.com/RookieOne/Learning

5.27.2010

Virtual Brown Bag 5/27/2010

Claudio was a no show today. As I predicted he had meetings he could not get out of.

But we powered through and covered a range of topics.

Wizards of Smart podcasts

Since our last meeting there have been 2 episodes of Wizards of Smart.

Episode 3 – Testing : http://www.theabsentmindedcoder.com/2010/05/wizards-of-smart-episode-3-testing.html

Episode 4 – Code Reviews, Work Environment, Developers : http://www.theabsentmindedcoder.com/2010/05/wizards-of-smart-episode-4.html

Ruby on Rails

I talked a bit about my experience this week with Ruby on Rails. In particular I pointed out how I enjoyed the migration functionality.

http://guides.rubyonrails.org/migrations.html

Alper pointed out that c4mvc also has a session on some .net tools for migration :

http://www.c4mvc.net/Home/Events –> March Show and Tell : Topic Database Migration Frameworks : MigratorDotNet and RikMigrations

I also point out the Dev Chix wiki for learning Ruby on Rails : http://wiki.devchix.com/index.php?title=Server_2003

The guide walks through every step from installing Ruby, rails gems, setting up git, heroku, and pushing your app to heroku. It’s a great guide for those new to rails (like me!)

SQLite Database Browser

I pointed out this tool for looking at Sqlite databases. I am using it to look at my rails database.

http://sourceforge.net/projects/sqlitebrowser/

Domain Driven Design

Ed asked about DDD for everyday apps. I then fumbled around and gave a high level talk on how to apply some DDD principles to everyday code. I think I will work on a presentation on the subject because I find it an interesting perspective.

We did point out some DDD resources :

Greg Young on Herding Code : http://herdingcode.com/?p=189

Greg Young on InfoQ : http://www.infoq.com/interviews/greg-young-ddd

David Laribee on Deep Fried Bytes : http://deepfriedbytes.com/podcast/episode-6-talking-domain-driven-design-with-david-laribee-part-1/

Eric Evan’s book : http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?ie=UTF8&s=books&qid=1274981635&sr=8-1

Jimmy Nilsson’s book : http://www.amazon.com/Applying-Domain-Driven-Design-Patterns-Examples/dp/0321268202/ref=sr_1_2?ie=UTF8&s=books&qid=1274981635&sr=8-2

Houston Techfest

I mentioned the Houston Techfest again and discussed some potential presentations Claudio and I might be doing.

http://www.houstontechfest.com/dotnetnuke/default.aspx

They are still taking abstracts. Email your abstracts and bio to speakers@houstontechfest.com

Linq

I walked through some linq examples that can be found in my learning C# project in my Learning Repository : http://github.com/RookieOne/Learning

We looked at Select, my pet peeve of using a Where and then FirstorDefault, and also how to use Any instead of Count to verify if a list is not empty.

I took a poll and there was a lot of interest in doing more Linq best practices and techniques. I am working on a presentation as well and it was nice to see there was a good deal of interest.

Wizards of Smart - Episode 4

Ryan and I talk about code reviews, work environment, and some traits of a good developer
 

5.26.2010

Structure Map 2.6 Constructor Arguments

Constructor Injection

When we use an IoC tool the most basic functionality we expect is to have constructor injection. That means if we have a type we are resolving and one of the constructor’s parameters is also a type, the container will resolve that type as well.

And turtles all the way down…

If we have two types(Foo : IFoo and Bar : IBar) and in Bar’s constructor it has an IFoo parameter, we should expect the IFoo parameter to be resolved to an instance of Foo.

class Bar : IBar
{
    public Bar(IFoo foo)
    {
        Foo = foo;
    }

    public IFoo Foo { get; set; }
}

Our container is setup like :

_container = new Container();

_container.Configure(x =>
                         {
                             x.For<IFoo>().Use<Foo>();
                             x.For<IBar>().Use<Bar>();
                         });

We then expect :

[Test]
public void IBar_should_resolve_to_Bar()
{
    var bar = _container.GetInstance<IBar>();

    bar.ShouldBeType<Bar>();
}

[Test]
public void IBars_IFoo_dependency_should_resolve_to_Foo()
{
    var bar = _container.GetInstance<IBar>();

    bar.Foo.ShouldBeType<Foo>();
}

Constructor Arguments

Sometimes you need to specify the exact argument for a given type when it is constructed. Structure Map allows you to provide specific values for resolving a constructors argument.

For example, Ryan was asking if there is a method with SM to resolve an “id” value from an HttpContext. I know SM has some fancy session management lifecycle features built in, but since I don’t live in the Web world I have never explored what can and can not be done with those features.

What I do know is that I can specify where my “id” parameter comes from.

Let’s look at this simple example.

In my scenario I have a Foo class.

class Foo : IFoo
{
    public Foo(int id, IBar bar)
    {
        Id = id;
        Bar = bar;
    }

    public int Id { get; set; }
    public IBar Bar { get; set; }
}

The id that is passed into Foo is providing by some mysterious X. In my case my X is an IIdProvider.

class IdProvider : IIdProvider
{
    public int GetId()
    {
        return 1;
    }
}

Now I want to tell SM that when it resolves an IFoo, I want it to use the IIdProvider to get the “id”.

x.For<IFoo>().Use<Foo>()
    .Ctor<int>("id")
    .Is(c => c.GetInstance<IIdProvider>().GetId());

All together the configuration is:

_container = new Container();
_container.Configure(x =>
                         {
                             x.For<IIdProvider>().Use<IdProvider>();
                             x.For<IBar>().Use<Bar>();
                             x.For<IFoo>().Use<Foo>()
                                 .Ctor<int>("id")
                                 .Is(c => c.GetInstance<IIdProvider>().GetId());
                         });

And my tests to verify it works:

[Test]
public void should_resolve_Bar()
{
    var foo = _container.GetInstance<IFoo>();

    foo.Bar.ShouldBeType<Bar>();
}

[Test]
public void should_resolve_id()
{
    var foo = _container.GetInstance<IFoo>();

    foo.Id.ShouldBe(1);
}

Lazy Constructor Arguments

Then Ryan tells me, he would really like to be lazy because he might not need the id for all requests. There are some Lazy features added to SM 2.6 but let’s just use what we already know to solve this problem.

Instead of having an int Id parameter, let’s have a Func<int> getId parameter.

Foo changes to :

class Foo : IFoo
{
    public Foo(Func<int> getId, IBar bar)
    {
        GetId = getId;
        Bar = bar;
    }

    public Func<int> GetId { get; set; }
    public IBar Bar { get; set; }
}

Now our constructor configuration changes to :

x.For<IFoo>().Use<Foo>()
    .Ctor<Func<int>>("getId")
    .Is(c => c.GetInstance<IIdProvider>().GetId);

And our tests become :

[Test]
public void should_resolve_Bar()
{
    var foo = _container.GetInstance<IFoo>();

    foo.Bar.ShouldBeType<Bar>();
}

[Test]
public void should_resolve_id()
{
    var foo = _container.GetInstance<IFoo>();

    foo.GetId().ShouldBe(1);
}

Yes it is a poor man’s lazy instantiation. But in many ways its the clearest way to have the functionality.

You can find all this code in my Git Hub Learning Repository and the Learning Structure Map solution : http://github.com/RookieOne/Learning

5.25.2010

Wizards of Smart – Episode 3 Testing

 
Ryan and I talk a bit about testing, TDD, code coverage, code quality, Dependency Injection…. so a bunch of random topics loosely related to testing.
 

5.24.2010

Structure Map 2.6 using Conventions

An awesome feature of StructureMap is the ability to scan assemblies and register types using different conventions. At first this might seem a trivial feature but I had a project in the past where this approach was shunned  upon. Even when I tried to bring in this functionality it was not approved. The result? A ‘module’ class with tons of namespaces and tons of register lines. Why suffer that pain?!

Default Convention

How many times do we have an IFoo interface and then the concrete implementation named Foo. Shouldn’t our IoC container be smart enough to recognized this most basic and popular pattern? Well StructureMap is that smart.

To use conventions, we first specify which assemblies we want to scan. Then we add conventions to use when scanning those assemblies. So to use the default convention scanner we simply do:

container.Configure(x => x.Scan(s =>
                                    {
                                        s.TheCallingAssembly();
                                                                                                   
                                        s.Convention<DefaultConventionScanner>();                                                    
                                    } ));

And naturally we should have a test to verify it works as we expect.

[Test]
public void should_load_IFoo()
{
    var container = new Container();

    container.Configure(x => x.Scan(s =>
                                        {
                                            s.TheCallingAssembly();
                                                                                                       
                                            s.Convention<DefaultConventionScanner>();                                                    
                                        } ));

    // IFoo -> Foo
    // IWhatever -> Whatever
    var foo = container.GetInstance<IFoo>();

    foo.ShouldBeType<Foo>();
}

Add All Types

Sometimes we have more than one implementation of a given interface. For that scenario we can use the same scanning process but this time tell the scanner to add of types of a given interface.

s.AddAllTypesOf<IEntity>()

What’s even cooler is that we can add additional information to the registration. For example, what if we want to register all our IEntity types but use the actual type name as a key (PersonEntity –> ‘Person’). Easy peasy.

s.AddAllTypesOf<IEntity>().NameBy(t => t.Name.Replace("Entity", ""));

And our test?

[Test]
public void should_load_Person_Entity()
{
    var container = new Container();

    container.Configure(x => x.Scan(s =>
                                        {
                                            s.TheCallingAssembly();

                                            s.AddAllTypesOf<IEntity>().NameBy(t => t.Name.Replace("Entity", ""));
                                        }));

    var person = container.GetInstance<IEntity>("Person");

    person.ShouldBeType<PersonEntity>();
}

Custom Convention

Beyond the built in Default Convention and the ability to add all types, we can create our own custom conventions. These used to be called TypeScanners, but are now implementations of the IRegistrationConvention interface. I think the renaming was a good idea. I always had a hard time naming my scanners because I kept calling them conventions. Now I don’t have that problem anymore. :)

The interface is simple and has only one method you need to implement called Process.

public class CustomConvention : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        throw new NotImplementedException();
    }
}

For our custom convention we are going to register all types of IController and use the type name as the key. So this is similar to how we registered our IEntity but instead of using the AddAllTypes feature we are using a convention.

public class ControllerConvention : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        if (!type.CanBeCastTo(typeof (IController)))
            return;

        string name = GetName(type);

        registry.AddType(typeof (IController), type, name);
    }

    static string GetName(Type type)
    {
        return type.Name.Replace("Controller", "");
    }
}

And then to use our new conventions we just need to do:

_container = new Container();
_container.Configure(x => x.Scan(s =>
                                     {
                                         s.TheCallingAssembly();

                                         s.Convention<ControllerConvention>();
                                     }));

Here are the tests:

[Test]
public void should_use_register_a_single_controller()
{
    var count = _container.GetAllInstances<IController>().Count;

    count.ShouldBe(1);
}

[Test]
public void should_register_controller_for_person()
{
    var controller = _container.GetInstance<IController>("Person");

    controller.ShouldBeType<PersonController>();
}

Here we just covered the basics of using conventions and the assembly scanner with StructureMap to reduce wasteful registration code.

The code can be found in my learning solution on GitHub : http://github.com/RookieOne/Learning