Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Array Injection Using Unity Application Block v1.2

Earlier I mentioned the release of Enterprise Library 4.1 and Unity 1.2.


One of the new features in Unity is the injection of arrays. The Unity Documentation is pretty good on showing how to do this, but here is a more complete sample for those interested in using Unity to inject arrays.


 


Injecting Array of ILogFilter into ConsoleLogger using Unity


Similar to the Enterprise Library Logging Application Block, let’s pretend we have a custom ILogger Service, called ConsoleLogger, that accepts an array of ILogFilter into its constructor. The Console Logger will only log a message if it passes all the filters.


 



public interface ILogger


{


    void Log(LogMessage message);


}


 


public class ConsoleLogger : ILogger


{


    private readonly ILogFilter[] _filters;


 


    public ConsoleLogger(ILogFilter[] filters)


    {


        _filters = filters;


    }


 


    public void Log(LogMessage message)


    {


        foreach(var filter in _filters)


            if (!filter.CanLog(message))


                return;


 


        Console.WriteLine(message.Message);


    }


}


 


public class LogMessage


{


    public string Category { get; set; }


    public int Priority { get; set; }


    public string Message { get; set; }


}


 


We have two custom ILogFilter Classes, CategoryFilter and PriorityFilter, that can be used to filter messages based on the category and priority, respectively.


 



public interface ILogFilter


{


    bool CanLog(LogMessage message);


}


 


public class CategoryFilter : ILogFilter


{


    private readonly string[] _categories;


 


    /// <summary>


    /// Filters log messages by category.


    /// </summary>


    /// <param name=”categories”>The categories to log.</param>


    public CategoryFilter(string[] categories)


    {


        _categories = categories;


    }


 


    public bool CanLog(LogMessage message)


    {


        foreach (var category in _categories)


            if (message.Category.Equals(category, StringComparison.InvariantCultureIgnoreCase))


                return true;


 


        return false;


    }


}


 


public class PriorityFilter : ILogFilter


{


    private readonly int _lowerBound;


    private readonly int _upperBound;


 


    /// <summary>


    /// Filters log messages by priority.


    /// </summary>


    /// <param name=”lowerBound”>The minimum priority that will be logged.</param>


    /// <param name=”upperbound”>The maximum priority that will be logged.</param>


    public PriorityFilter(int lowerBound, int upperbound)


    {


        _lowerBound = lowerBound;


        _upperBound = upperbound;


    }


 


    public bool CanLog(LogMessage message)


    {


        return message.Priority >= _lowerBound && message.Priority <= _upperBound;


    }


}


 


Now that we have the infrastructure in place we need to configure our UnityContainer so that ConsoleLogger is our default ILogger and that any filters of our choosing get properly injected into ConsoleLogger at runtime.


 


 


Setting Up UnityContainer


We can configure our UnityContainer via configuration or using the Unity API at runtime. In this case I choose to configure Unity at runtime using its API.


First, let’s register both a CategoryFilter and PriorityFilter with the UnityContainer for injection into the ConsoleLogger. In this case, I am registering an instance that I will create myself.


 



IUnityContainer container = new UnityContainer();


 


container.RegisterInstance<ILogFilter>(“CategoryFilter”, new CategoryFilter(new[] {“Security”}));


container.RegisterInstance<ILogFilter>(“PriorityFilter”, new PriorityFilter(3, 5));


 


You don’t have to use RegisterInstance. You could just as easily read this from a configuration file or use RegisterType. In this case I am specifying that only LogMessages with a Category of “Security” and a priority of 3 to 5 inclusive will be logged.


 


I then register the ConsoleLogger as my default ILogger.


 



container.RegisterType<ILogger, ConsoleLogger>(new ContainerControlledLifetimeManager());


 


If you had multiple constructors and wanted to be more specific about using the constructor with 1 parameter accepting an array of ILogFilters, you can use InjectionConstructor with ResolvedParameter as such: 


 



container.RegisterType<ILogger, ConsoleLogger>(new ContainerControlledLifetimeManager(),


                                               new InjectionConstructor(


                                                   new ResolvedParameter<ILogFilter[]>()));


 


This works, too :) 


 



container.RegisterType<ILogger, ConsoleLogger>(new ContainerControlledLifetimeManager(),


                                               new InjectionConstructor(typeof(ILogFilter[])));


 


Alternatively, if you want to specify the array of ILogFilters at the same time as registering the ConsoleLogger, you can do it as such:


 



container.RegisterType<ILogger, ConsoleLogger>(new ContainerControlledLifetimeManager(),


                                          new InjectionConstructor(


                                              new ResolvedArrayParameter<ILogFilter>(


                                                  new CategoryFilter(new[] { “Security” }), new PriorityFilter(3, 5))));


 


I could have done this via a configuration file as well. You can check the documentation for the schema.


Once the ILogFilters and ILogger have been registered, you can resolve the ILogger and log a message:


 



var logger = container.Resolve<ILogger>();


 


logger.Log(new LogMessage { Category = “Security”, Priority = 3, Message = “This is a test.” });


 


In this case the message will be displayed on the console. 


 


 


Conclusion


In addition to injection of arrays, Unity v1.2 also has support for Generic Decorator Chains and various Interception Mechanisms ( InterfaceInterceptor, TransparentProxyInterceptor, and VirtualMethodInterceptor ). There is also better integration with the Policy Injection Application Block.


As an FYI, I have a couple of AOP presentations set-up early next year similar to the presentation I did on AOP for the Tampa IASA Chapter. I plan to cover Unity, PostSharp, Castle DynamicProxy / Windsor, SPRING.NET, and the Policy Injection Application Block to name a few.


Next time I will show another way of doing this that also involves Generic Decorator Chains. 


 


Hope this helps,


David Hayden


 


Recent Posts



 

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

One Response to Array Injection Using Unity Application Block v1.2

  1. Stephen says:

    Generally I wouldn’t want to take an array as a dependency, is unity looking for arrays or does it support IEnumerable ?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>