Showing posts with label Inversion of Control. Show all posts
Showing posts with label Inversion of Control. Show all posts

Monday, 29 August 2016

Choosing an IoC Container talk at Israeli .NET Developers User Group

Last week I had the honor to hold a talk at the Israeli .NET Developers User Group. The subject was "Choosing an IoC Container", but the main goal was not to choose the best container ever, rather to present different features of IoC Containers and provide the tools to compare between them. Based on the feedback I received from the survey, it achieved the goal.

I would like to share the slides and the code samples presented during the talk.



Wednesday, 4 December 2013

Goodbye Autofac

Autofac is one of my favorite IoC containers, due to its fluent, easy-to-learn syntax and great performance. However recently it let me down in some occasions and I had to get rid of it in the main project, I am working on. But let me explain it from the beginning.

Since Autofac 3.0, it is compiled against Portable .NET Framework. It is a subset of the usual .NET Framework, which runs on various devices and platforms. Such as Silverlight, mobile etc. The portable framework version number is 2.0.5.0. So far, so good. It worked well in my project with .NET Framework 4.5. But...

1. When we tried to obfuscate Autofac.dll using Dotfuscator version 4.8, it complained that mscorlib.dll version 2.0.5.0 cannot be found. Although it exists in the corresponding directory under C:\Windows\Microsoft.NET\Framework . Travis Illig suggested me to upgrade the Dotfuscator to latest version, which would definitely resolve the problem.

From Dotfuscator v 4.9 release notes:
  • Using String Encryption on Portable Class Libraries will no longer cause Windows Store apps to fail certification.
http://www.preemptive.com/support/dotfuscator-support/dotfuscator-pro-change-log/464

Unfortunately, upgrading Dotfuscator means purchasing a new license, which is pretty expensive. We managed to overcome this problem by putting mscorlib.dll v2.0.5.0 in one of the internal directories. Dotfuscator scans directories and managed to find it successfully.

2. The second problem appeared when we started testing the product on clean machines. We get the following exception, despite the fact that Portable Framework exists on the machine:

Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or one of its dependencies. 

It happens as a result of Microsoft Known Bug KB2468871. It was fixed by the Redmond folks, but the relevant update is not installed on the machine.

So it means, that in order to use Autofac we have to required from our customers to install Windows Updates. Sometimes it might cause issues with corporate customers, that have strict policy regarding machine updates. It was decided that we'll stop using Autofac in this major project and will switch to something less "sensitive".

Nevertheless, we still use Autofac in many other internal projects. So it is not a real "Goodbye"




Wednesday, 13 November 2013

Opt in and opt out using Autofac IoC container

I am a big fan of dependency injection and inversion of control. I strive to use these techniques in almost every project I am involved with. Usually when I develop the project from the ground, the whole design is ready for automatic types scanning and auto wiring. So it is very easy to wire them up using a short piece of code. All the examples in this post will be using Autofac - the addictive IoC container.
 
public IContainer Initialize()
{
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(GetType().Assembly).AsImplementedInterfaces();
    return builder.Build();
}

But sometimes, I need to prevent some classes from being registered, for example, the instance need to be created in run time with specific context parameters. In this case I use the opt-out, i.e. register all the types except those having a custom attribute:
 
[AttributeUsage(AttributeTargets.Class)]
public class DontRegisterInContainerAttribute : Attribute
{

}

public IContainer Initialize()
{
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(GetType().Assembly)
        .Where(t => !t.HasAttribute<DontRegisterInContainerAttribute>())
        .AsImplementedInterfaces();
    return builder.Build();
}
In order to use the attribute in this syntax, I am using an extension method:
 
public static class TypeExtensions
{
    public static bool HasAttribute<T>(this Type @this)
    {
        return @this.GetCustomAttributes(typeof (T), false).Any();
    }
}

In some projects, when I am modifying existing code, which is not "IoC-ready", I need to register only a few classes. Hopefully their number will increase in the future. But currently what I am actually want is to type the container: register only these classes, without actually listing them or assume they reside in some namespace or have something in their name. In such cases I use the opposite:
 
public IContainer Initialize()
{
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(GetType().Assembly)
        .Where(t => t.HasAttribute<RegisterInContainerAttribute>())
        .AsImplementedInterfaces();
    return builder.Build();
}

With the corresponding custom attribute:
 
[AttributeUsage(AttributeTargets.Class)]
public class RegisterInContainerAttribute : Attribute
{
         
}

Using this method of registering only types marked with the attribute also makes the code clearer to co-workers, who might look up for usages of the attribute and find out what classes are registered in the container. In case they are not familiar with Agent Mulder Resharper plugin.


Sunday, 4 August 2013

Type safe configuration mapper

Almost every project needs some sort of configuration, that is external of the source code. Sometimes we spend time to find the best library that fits our needs and sometimes we give up and write something in-house. I would like to save your time in both these tasks and suggest what I have found and I use in my projects.

I was looking for a library that would allow me to represent all parameters as an interface or class. The parameters would be strongly typed with minimum overhead in mapping parameter to property. Providing default values would be also nice, but not necessarily. The best library that exactly fits these needs is ConfigReader. Here are a few simple steps how to use it in your project:

1. Put your configuration parameters in the regular app.config or web.config file. Parameters may be of any primitive data types:
 

 <appsettings>
    <add key="ApplicationConfiguration.Duration" value="30" />
    <add key="ApplicationConfiguration.Distance" value="3" />
    <add key="ApplicationConfiguration.Author" value="Boris Modylevsky" />
 </appsettings>

2. Create an interface with properties to represent the configuration in code. Give properties the same names as parameters names. Properties may be read-only - having only getter without setter. We don't need to specify no special mapping attributes, nothing. Just an interface with properties. Here is a corresponding interface:
 

public interface IApplicationConfiguration
{
    int Duration { get; }
    double Distance { get; }
    string Author { get; }
}
3. Next step we need to initialize our configuration interface from the configuration file. If you are using Inversion of Control (IoC) containers, it is better to to in the bootstrapper - where all the classes are registered in the container. I will show how this could be done in Autofac. First of all we create a ConfigurationModule class, which defines configuration registration in Autofac:
 
using System.Diagnostics.Contracts;
using Autofac;
using ConfigReader;

public class ConfigurationModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        Contract.Assert(builder != null, "Builder container is null");

        var configReader = new ConfigurationReader().SetupConfigOf<IApplicationConfiguration>();
        var configuration = configReader.ConfigBrowser.Get<IApplicationConfiguration>();
        builder.RegisterInstance(configuration).As<IApplicationConfiguration>();
    }
}
4. Then we just register the ConfigurationModule in our container builder and that's all!
 

using Autofac;

public static class Bootstrapper
{
    public static IContainer Container { get; private set; }

    public static IContainer Initialize()
    {
        var containerBuilder = new ContainerBuilder();
        containerBuilder.RegisterModule<ConfigurationModule>();
        Container = containerBuilder.Build();
        return Container;
    }
}
5. Use it by defining as constructor parameter. IoC container will take care to transfer the correct instance into your constructor:
 
public class SomeClassThatUsesConfiguration
{
    private readonly IApplicationConfiguration _configuration;

    public SomeClassThatUsesConfiguration(IApplicationConfiguration configuration)
    {
        _configuration = configuration;
    }

    public double GetVelocity()
    {
        return _configuration.Distance/_configuration.Duration;
    }
}
If you like the above and would like to use it in your project, download it from nuget.org:

PM> Install-Package ConfigReader