Unity.Patterns provides extensions for Unity dependency injection framework. The main focus is on Registration by Convention and the Decorator pattern.
NuGet package:
A common way to use Unity's support for Register by Convention looks like this:
container.RegisterTypes(
AllClasses.FromAssembliesInBasePath(),
WithMapping.MatchingInterface,
WithName.Default,
WithLifetime.Hierarchical);
This library provides a replacement for AllClasses.FromAssembliesInBasePath()
called TypeLocator.FromAssembliesInSearchPath()
. Unlike the Unity method this respects AppDomain.CurrentDomain.RelativeSearchPath
if set. This is important for ASP.NET applications where the binaries are commonly located in a subdirectory called bin
.
This library also provides LifetimeMap
, an alternative to manually creating lambdas that build LifetimeManager
s:
var map = new LifetimeMap(defaultLimetime: WithLifetime.Hierarchical)
.Add<MySingleton>(WithLifetime.ContainerControlled)
.Add<MyTransientService>(WithLifetime.Transient);
container.RegisterTypes(
AllClasses.FromAssembliesInBasePath(),
WithMapping.MatchingInterface,
WithName.Default,
map);
Alternatively, you can also use the C# 6.0 dictionary initialization syntax:
var map = new LifetimeMap(defaultLimetime: WithLifetime.Hierarchical)
{
[typeof(MySingleton)] = WithLifetime.ContainerControlled,
[typeof(MyTransientService)] = WithLifetime.Transient
};
This library provides an alternative extension method to perform Registration by Convention, that hardcodes to WithMapping.MatchingInterface
and WithName.Default
and defaults to WithLifetime.Hierarchical
:
container.RegisterByConvention();
This can be combined with LifetimeMap
:
container.RegisterByConvention(new LifetimeMap
{
[typeof(MySingleton)] = WithLifetime.ContainerControlled,
[typeof(MyTransientService)] = WithLifetime.Transient
});
The Decorator pattern allows you to wrap one or more intercepting layers around an object that all implement the same interface.
After adding the DecoratorExtension
to your Unity container you can register multiple implementations for a single interface. Start from outermost and move inwards:
container.AddNewExtension<DecoratorExtension>();
container.RegisterType<IMyService, MyServiceDecorator2>();
container.RegisterType<IMyService, MyServiceDecorator1>();
container.RegisterType<IMyService, MyService>();
The extension method .RegisterDecorators()
and the class .DecoratorStack<>
provide a more declarative alternative. Start from innermost and move outwards:
container.RegisterDecorators(new DecoratorStack<IMyService>()
.Push<MyService>()
.Push<MyServiceDecorator1>()
.Push<MyServiceDecorator2>());
IMPORTANT: When combining the Decorator feature with Registration by Convention the Decorator configuration MUST be applied to the Unity container first in order to work properly!