Custom object factory extension for Unity - c#

I am using the Unity IoC container, and I need to intercept any calls to Resolve for a certain base interface, and run my own custom code to construct those types.
In other words, in the sample code below, when I call container.Resolve<IFooN>(), if it hasn't got an instance of the concrete implementing type, it calls MyFactoryFunction to construct one, otherwise I want it to return the cached copy.
The standard Unity container is not able to construct these objects (update: because they are .NET remoting objects, so the concrete classes do not exist in any assembly on the local computer), and I don't want to create them up front and store them with RegisterInstance.
interface IFoo : IBase { ... }
interface IFoo2 : IBase { ... }
...
container.Resolve<IFoo2>();
...
IBase MyFactoryFunction(Type t)
{
...
}
I'm assuming I can create a Unity extension to do this, but I was wondering if there is already a solution out there I can borrow.

For completeness, I should add another answer that works under Unity 2, since my other answer no longer works. It is slightly more involved since you need to make a custom builder policy. Thanks to ctavares from the Unity project who provided lots of help on this thread in implementing this:
public class FactoryUnityExtension : UnityContainerExtension
{
private ICustomFactory factory;
private CustomFactoryBuildStrategy strategy;
public FactoryUnityExtension(ICustomFactory factory)
{
this.factory = factory;
}
protected override void Initialize()
{
this.strategy = new CustomFactoryBuildStrategy(factory, Context);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
Context.Policies.Set<ParentMarkerPolicy>(new ParentMarkerPolicy(Context.Lifetime), new NamedTypeBuildKey<ParentMarkerPolicy>());
}
}
public class ParentMarkerPolicy : IBuilderPolicy
{
private ILifetimeContainer lifetime;
public ParentMarkerPolicy(ILifetimeContainer lifetime)
{
this.lifetime = lifetime;
}
public void AddToLifetime(object o)
{
lifetime.Add(o);
}
}
public interface ICustomFactory
{
object Create(Type t);
bool CanCreate(Type t);
}
public class CustomFactoryBuildStrategy : BuilderStrategy
{
private ExtensionContext baseContext;
private ICustomFactory factory;
public CustomFactoryBuildStrategy(ICustomFactory factory, ExtensionContext baseContext)
{
this.factory = factory;
this.baseContext = baseContext;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = (NamedTypeBuildKey)context.OriginalBuildKey;
if (factory.CanCreate(key.Type) && context.Existing == null)
{
context.Existing = factory.Create(key.Type);
var ltm = new ContainerControlledLifetimeManager();
ltm.SetValue(context.Existing);
// Find the container to add this to
IPolicyList parentPolicies;
var parentMarker = context.Policies.Get<ParentMarkerPolicy>(new NamedTypeBuildKey<ParentMarkerPolicy>(), out parentPolicies);
// TODO: add error check - if policy is missing, extension is misconfigured
// Add lifetime manager to container
parentPolicies.Set<ILifetimePolicy>(ltm, new NamedTypeBuildKey(key.Type));
// And add to LifetimeContainer so it gets disposed
parentMarker.AddToLifetime(ltm);
// Short circuit the rest of the chain, object's already created
context.BuildComplete = true;
}
}
}

Update This answer was for Unity 1.2. For a solution that works with Unity 2, see my other answer.
OK, I have implemented the extension myself. In the builder I cache the object as I want it to be a singleton w.r.t my container. The reason for baseContext is that I want it to be cached in the top level container rather than in any child containers from which it was requested.
public class FactoryMethodUnityExtension<T> : UnityContainerExtension
{
private Func<Type,T> factory;
public FactoryMethodUnityExtension(Func<Type,T> factory)
{
this.factory = factory;
}
protected override void Initialize()
{
var strategy = new CustomFactoryBuildStrategy<T>(factory, this.Context);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
}
public class CustomFactoryBuildStrategy<T> : BuilderStrategy
{
private Func<Type,T> factory;
private ExtensionContext baseContext;
public CustomFactoryBuildStrategy(Func<Type,T> factory, ExtensionContext baseContext)
{
this.factory = factory;
this.baseContext = baseContext;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = (NamedTypeBuildKey)context.OriginalBuildKey;
if (key.Type.IsInterface && typeof(T).IsAssignableFrom(key.Type))
{
object existing = baseContext.Locator.Get(key.Type);
if (existing == null)
{
// create it
context.Existing = factory(key.Type);
// cache it
baseContext.Locator.Add(key.Type, context.Existing);
}
else
{
context.Existing = existing;
}
}
}
}
Adding the extension is quite simple:
MyFactory factory = new MyFactory();
container = new UnityContainer();
container.AddExtension(new FactoryMethodUnityExtension<IBase>(factory.Create));

Unity (v2) allows you to specify a factory. It allows a couple of different functions, including taking the type to build up/ name, etc. Simple example:
UnityContainer cont = new UnityContainer();
have a simple create test method - but this can be expanded with whatever factory you want.
this will circumvent the normal creation process which is (for the sake of brevity) call the
longest constructor
all later behaviors including propert setting will still be executed.
cont.RegisterType<TestClass>(new InjectionFactory(c => CreateTest()));
var svc = cont.Resolve<TestClass>();

The Unity container already acts as a factory that knows how to construct (and perform dependency injection for) arbitrary types, so your factory that accepts a Type t appears redundant. Can you elaborate more on why this is not possible?
If this is truly not possible (more likely just too much work), then perhaps you can register your factory with the container instead?

Related

Generic Static Class as Service Locator

I am applying the Service Locator pattern as described in Game Programming Patterns, and am wondering about a possible generic implementation. The following code does work, but I am confused about using a class that is both generic and static.
The idea of the following C# code is to provide a "global" service to other parts of the application, exposing only an interface rather than the full implementation. Each service registered using this method will only have one instance in the application, but I want to be able to easily swap in/out different implementations of the provided interfaces.
My question is: when I use the following class to provide different services throughout my application, how does C# know that I am referring to different services of different types? Intuitively, I would almost think that the static variable, _service, would be overridden with each new service.
public static class ServiceLocator<T>
{
static T _service;
public static T GetService()
{
return _service;
}
public static void Provide(T service)
{
_service = service;
}
}
Here's some usage:
// Elsewhere, providing:
_camera = new Camera(GraphicsDevice.Viewport);
ServiceLocator<ICamera>.Provide(_camera);
// Elsewhere, usage:
ICamera camera = ServiceLocator<ICamera>.GetService();
// Elsewhere, providing a different service:
CurrentMap = Map.Create(strategy);
ServiceLocator<IMap>.Provide(CurrentMap);
// Elsewhere, using this different service:
IMap map = ServiceLocator<IMap>.GetService();
C# creates a separate closed type for every combination of generic parameters for open type.
Since every combination of generic parameters creates a separate class, calling a static constructor and creating own members for each of them.
You can think of them like of different classes.
public static class GenericCounter<T>
{
public static int Count { get; set; } = 0;
}
GenericCounter<int>.Count++;
GenericCounter<int>.Count++;
GenericCounter<string>.Count++;
Console.WriteLine(GenericCounter<double>.Count); // 0
Console.WriteLine(GenericCounter<int>.Count); // 2
Console.WriteLine(GenericCounter<string>.Count); // 1
This code outputs:
0
2
1
For example, in your case, behavior will be the same as if you created two separate classes:
public static class ServiceLocatorOfIMap
{
static IMap _service;
public static IMap GetService()
{
return _service;
}
public static void Provide(IMap service)
{
_service = service;
}
}
public static class ServiceLocatorOfICamera
{
static ICamera _service;
public static ICamera GetService()
{
return _service;
}
public static void Provide(ICamera service)
{
_service = service;
}
}
and used it like this:
// Elsewhere, providing:
_camera = new Camera(GraphicsDevice.Viewport);
ServiceLocatorForICamera.Provide(_camera);
// Elsewhere, usage:
ICamera camera = ServiceLocatorForICamera.GetService();
// Elsewhere, providing a different service:
CurrentMap = Map.Create(strategy);
ServiceLocatorForIMap.Provide(CurrentMap);
// Elsewhere, using this different service:
IMap map = ServiceLocatorForIMap.GetService();
In general, it is similar to what C# does when it meets static generic classes.
I use this for cases where I can't use dependency injection all the way down (like WebForms) but I want to write testable classes that are resolved by a DI container.
The usage looks like
using(var resolved = new ResolvedService<ISomeService>())
{
resolved.Service.DoSomething();
}
The good:
You can use a DI container to resolve and release resources
It's disposable, and disposing causes the container to release the resources
It keeps the container and service registrations out of sight
The bad:
It requires a static class, but that's also in the composition root so it's not too bad.
As written it depends directly on Windsor. It's easy to replace that with any other container. Maybe one day I'll break this apart so that ServiceLocator isn't coupled to any particular container. But for now it's trivial to change that.
Using this means that while the larger component (like an .aspx page) isn't testable, what I inject into it is testable. It just gave me a crazy thought - I could write orchestrators for WebForms pages so that they're mostly testable. But hopefully I'll never need to do that.
internal class ServiceLocator
{
private static IWindsorContainer _container;
internal static void Initialize(IWindsorContainer container)
{
_container = container;
}
internal static TService Resolve<TService>(string key = null)
{
if (_container == null)
{
throw new InvalidOperationException(
"ServiceLocator must be initialized with a container by calling Initialize(container).");
}
try
{
return string.IsNullOrEmpty(key)
? _container.Resolve<TService>()
: _container.Resolve<TService>(key);
}
catch (ComponentNotFoundException ex)
{
throw new InvalidOperationException(string.Format("No component for {0} has been registered.", typeof(TService).FullName), ex);
}
}
internal static void Release(object resolved)
{
_container.Release(resolved);
}
}
public class ResolvedService<TService> : IDisposable
{
private bool _disposed;
private readonly TService _resolvedInstance;
public TService Service
{
get { return _resolvedInstance; }
}
public ResolvedService(string key = null)
{
_resolvedInstance = ServiceLocator.Resolve<TService>(key);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~ResolvedService()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
ServiceLocator.Release(_resolvedInstance);
_disposed = true;
}
}

Is Service Locator an anti pattern in a pluggable architecture?

I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)

Circular reference using IoC

I am using windsor castle as my IoC container, and has run in to a bit of a problem.
First of all - i know about: Castle Windsor: How to prevent circular references in factory-created objects were the created objects refers back to the factory
But since circular reference is considered as "Code Smell" and i should consider refactoring app architecture i am asking anyway.
I have very similar situation:
public class OperationsFactory
{
private GeneralSettingsManager m_generalSettings;
private Dictionary<OperationType, OperationCreatorBase> m_creators;
public OperationsFactory(IKernel container)
{
m_generalSettings = container.Resolve<GeneralSettingsManager>();
var creators = container.ResolveAll<OperationCreatorBase>(); //FIRST DEPENDENCY
foreach (var creator in creators)
{
m_creators.Add(creator.CreatorOperationType, creator);
}
}
.
.
.
private OperationCreatorBase GetCreator(OperationType operationType)
{
return m_creators[operationType];
}
}
Now i would like to take in code this OperationFactory from windsor container so i can easily read all the successors of OperationCreatorBase.
now there is a code for OperationCreator:
public class ConvertToFullOperationCreator : OperationCreatorBase
{
private OperationsFactory m_operationsFactory;
private SomeHelper m_someHelper;
public ConvertToFullOperationCreator(IKernel container)
{
m_operationsFactory = container.Resolve<OperationsFactory>(); //SECOND dependency which causes error
m_someHelper = container.Resolve<SomeHelper>();
}
public override OperationType CreatorOperationType
{
get { return OperationType.SomeOperation2; }
}
public override List<OperationBase> CreateOperation(FileData fileData)
{
//HERE I WANT TO USE FACTORY to get creators for SUBOPERATIONS
var creator1 = m_operationsFactory.GetCreator(OperationType.SomeSuboperation1);
creator1.CreateOperation(fileData);
.
.
.
m_someHelper.DoSomething(fileData);
var creator2 = m_operationsFactory.GetCreator(OperationType.SomeSuboperation2);
creator2.CreateOperation(fileData);
.
.
.
}
}
I really want to use windsor castle for both of this classes because i am using more components (such as SomeHelper in creator... and more). In factory class i am using nice method ResolveAll provided by IKernel.
There is obvious constructor circular reference but i cant figure out, whats wrong with this component design and most important - how to make this runnable.
I know i can do it with Property Injection on both sides but this kills this nice dependency injection feature, so thats why the answer said in upper stackoverflow question wont solve my problem. Am i missing something?
Is there any suggestion how to redesign those two components or how to Split the "C" class said in nice article about circular reference here: http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/
In order to solve cyclic dependency you should inject Func<OperationsFactory> instead of OperationsFactory via constructor (or resolve using IKernel/ IWindsorContainer).
public class ConvertToFullOperationCreator : OperationCreatorBase
{
private Func<OperationsFactory> get_operationsFactory;
private SomeHelper m_someHelper;
public ConvertToFullOperationCreator(
SomeHelper someHelper,
Func<OperationsFactory> get_operationsFactory)
{
this.get_operationsFactory = get_operationsFactory
m_someHelper = someHelper;
}
public override List<OperationBase> CreateOperation(FileData fileData)
{
var m_operationsFactory = get_operationsFactory()
// Here you can place all your code
var creator1 = m_operationsFactory
.GetCreator(OperationType.SomeSuboperation1);
...
var creator2 = m_operationsFactory
.GetCreator(OperationType.SomeSuboperation2);
...
}
}
First OperationsFactory should be registered, then Func<OperationsFactory>.
container.Register(Component.For<Func<OperationsFactory>>()
.UsingFactoryMethod(container =>
{
Func<OperationsFactory> func = container.Resolve<OperationsFactory>;
return func;
}));
I've already answered the similar question Cyclic dependency with Castle Windsor IoC for NHibernate ISession. You can find more details there.
If you already use IoC container it is better to inject instances of concrete types via constructor instead of IKernel. IKernel is a part of your infrastructure.
In order to resolve IEnumerable<T> CollectionResolver can be used.
public class OperationsFactory
{
private GeneralSettingsManager m_generalSettings;
private Dictionary<OperationType, OperationCreatorBase> m_creators;
public OperationsFactory(
GeneralSettingsManager generalSettings,
IEnumerable<OperationCreatorBase> creators)
{
m_generalSettings = generalSettings;
foreach (var creator in creators)
{
m_creators.Add(creator.CreatorOperationType, creator);
}
}
...
}
EDIT :
If you cannot register Func<OperationsFactory> you can create it in the constructor in order to load OperationsFactory lazily.
public class ConvertToFullOperationCreator : OperationCreatorBase
{
private Func<OperationsFactory> get_operationsFactory;
private SomeHelper m_someHelper;
public ConvertToFullOperationCreator(
IKernel container)
{
this.get_operationsFactory = () => container.Resolve<OperationsFactory>;
m_someHelper = container.Resolve<SomeHelper>();
}
public override List<OperationBase> CreateOperation(FileData fileData)
{
var m_operationsFactory = get_operationsFactory()
// Here you can place all your code
var creator1 = m_operationsFactory
.GetCreator(OperationType.SomeSuboperation1);
...
var creator2 = m_operationsFactory
.GetCreator(OperationType.SomeSuboperation2);
...
}
}

Use Unity to intercept all calls to IMyInterface.SomeMethod

I am trying to learn Unity Interceptors and I am having a hard go of it.
Say I have an interface like this:
public interface IMyInterface
{
void SomeMethod();
}
And I have an unknown number of classes that implement that interface like this:
public class SpecificClass1 : IMyInterface
{
public void SomeMethod()
{
Console.WriteLine("Method Called");
}
}
I am looking for a way to say, "for all instance of IMyInterface (I don't want to enumerate them), when SomeMethod is called run my interceptor.
It is the Non-Enumeration of the classe that is giving me trouble. (There are plenty of examples if you can enumerate all your classes.)
I have read of Type Interception, but I can't seem to find out if it will do what I am looking for.
Any Unity experts out there know how to do what I am looking for?
You could create InterceptionBehavior then register it on specific class. Note you could filter executing methods in Invoke thru IMethodInvocation input
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using NUnit.Framework;
namespace UnitTests
{
[TestFixture]
public class ForTest
{
[Test]
public void Test()
{
IUnityContainer container = new UnityContainer().AddNewExtension<Interception>();
container.RegisterType<IMyInterface, SpecificClass1>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<MyInterceptionBehavior>());
var myInterface = container.Resolve<IMyInterface>();
myInterface.SomeMethod();
}
}
public interface IMyInterface
{
void SomeMethod();
}
public class SpecificClass1 : IMyInterface
{
#region IMyInterface
public void SomeMethod()
{
Console.WriteLine("Method Called");
}
#endregion
}
public class MyInterceptionBehavior : IInterceptionBehavior
{
public bool WillExecute
{
get { return true; }
}
#region IInterceptionBehavior
public IEnumerable<Type> GetRequiredInterfaces()
{
return Enumerable.Empty<Type>();
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
IMethodReturn result = getNext()(input, getNext);
Console.WriteLine("Interception Called");
return result;
}
#endregion
}
}
Console output
Method Called
Interception Called
More about Interception with Unity
#GSerjo, has outlined the Unity interception approach which works well. If you wanted to automate the configuration of interception you can use a UnityContainerExtension to automatically wire up all the interface interception as well as the behaviors. If you wanted to get into more specific interception (method names, signatures, return values etc.) then you would probably need to look at Policy Injection (using matching rules with CallHandlers).
So in this case the container extension would look like:
public class UnityInterfaceInterceptionRegisterer : UnityContainerExtension
{
private List<Type> interfaces = new List<Type>();
private List<IInterceptionBehavior> behaviors =
new List<IInterceptionBehavior>();
public UnityInterfaceInterceptionRegisterer(Type interfaceType,
IInterceptionBehavior interceptionBehavior)
{
interfaces.Add(interfaceType);
behaviors.Add(interceptionBehavior);
}
public UnityInterfaceInterceptionRegisterer(Type[] interfaces,
IInterceptionBehavior[] interceptionBehaviors)
{
this.interfaces.AddRange(interfaces);
this.behaviors.AddRange(interceptionBehaviors);
ValidateInterfaces(this.interfaces);
}
protected override void Initialize()
{
base.Container.AddNewExtension<Interception>();
base.Context.Registering +=
new EventHandler<RegisterEventArgs>(this.OnRegister);
}
private void ValidateInterfaces(List<Type> interfaces)
{
interfaces.ForEach((i) =>
{
if (!i.IsInterface)
throw new ArgumentException("Only interface types may be configured for interface interceptors");
}
);
}
private bool ShouldIntercept(RegisterEventArgs e)
{
return e != null && e.TypeFrom != null &&
e.TypeFrom.IsInterface && interfaces.Contains(e.TypeFrom);
}
private void OnRegister(object sender, RegisterEventArgs e)
{
if (ShouldIntercept(e))
{
IUnityContainer container = sender as IUnityContainer;
var i = new Interceptor<InterfaceInterceptor>();
i.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies);
behaviors.ForEach( (b) =>
{
var ib = new InterceptionBehavior(b);
ib.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies);
}
);
}
}
}
Then you could use it like so:
IUnityContainer container = new UnityContainer()
.AddExtension(new UnityInterfaceInterceptionRegisterer(
new Type[] { typeof(IMyInterface),
typeof(IMyOtherInterface) },
new IInterceptionBehavior[] { new MyInterceptionBehavior(),
new AnotherInterceptionBehavior() }
));
container.RegisterType<IMyInterface, SpecificClass1>();
var myInterface = container.Resolve<IMyInterface>();
myInterface.SomeMethod();
Now when the interface is registered the appropriate interception policies will also be added to the container. So in this case if the interface registered is of type IMyInterface or IMyOtherInterface then policies will be setup for interface interception and the Interception Behaviors MyInterceptionBehavior and AnotherInterceptionBehavior will also be added.
Note that Unity 3 (released after this question/answer) added a Registration by Convention feature that can do what this extension does (without having to write any custom code). An example from the Developer's Guide to Dependency Injection Using Unity:
var container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterTypes(
AllClasses.FromLoadedAssemblies().Where(
t => t.Namespace == "OtherUnitySamples"),
WithMappings.MatchingInterface,
getInjectionMembers: t => new InjectionMember[]
{
new Interceptor<VirtualMethodInterceptor>(),
new InterceptionBehavior<LoggingInterceptionBehavior>()
});
Setting up interception requires multiple actions incl. configuration of intercepted types, policies and handlers.
First see Using Interception in Applications for general details about the types of situations where interception is supported (with or without a DI container for example). Then see Type Interception for more details about the supported type interceptors. Especially take note of what interceptors can be used with the type of your class (otherwise the handlers will never trigger).
When you have decided what interceptor to use, configure it and create a sufficient call handler as per the links above. If you still have trouble at this point, post a more detailed question. If you have already done this, please post the configs and code as "non-enumeration of the classe" simply does not give any hints what you are actually asking. Do you by any chance mean with "enumeration" that you assign a attribute-driven policy and are unable to achieve what you want without it?

How to remove(unregister) registered instance from Unity mapping?

I meet one problem that i can't solve now.
I have the following:
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance);
where UnityHelper.DefaultContainer is my helper for getting unity container with loaded configuration.
here I registered instance as an instance of IMyInterface.
So anywhere( some time after using) I want to remove this mapping. Remove it at all. How I can do it?
I have tried:
UnityHelper.DefaultContainer.Teardown(instance)
but is was unsuccessful and the following code returns instance anyway:
UnityHelper.DefaultContainer.ResolveAll<IMyInterface>()
I had the same problem and just removed the registrations of the ContainerControlledLifetimeManager from my Container:
foreach (var registration in container.Registrations
.Where(p => p.RegisteredType == typeof(object)
&& p.Name == name
&& p.LifetimeManager.Type == typeof(ContainerControlledLifetimeManager)))
{
registration.LifetimeManager.RemoveValue();
}
This is an old question, but some answers are misleading, so I will provide my own.
You can´t do that with Unity. End of the story.
Calling RemoveValue on registrations lifetime managers does not achieve unregistration (more information about lifetime managers), and that method is not intended to unregister anything. So the final behaviour is unexpected and not convenient. Of course, RemoveValue makes even less sense if you register an implementation or a factory method, although the question is about unregistering instances.
Consider the next piece of code
public interface SomeInterface
{
int Foo { get; set; }
}
public class SomeImplementation: SomeInterface
{
public int Foo { get; set; }
}
static void Main(string[] args)
{
UnityContainer iocContainer = new UnityContainer();
string registerName = "instance";
//before any registration
Resolve<SomeInterface>(iocContainer, registerName);
iocContainer.RegisterInstance<SomeInterface>(registerName, new SomeImplementation());
//after registration
Resolve<SomeInterface>(iocContainer, registerName);
ClearValue<SomeInterface>(iocContainer, registerName);
//after clear value
Resolve<SomeInterface>(iocContainer, registerName);
}
private static void Resolve<T>(UnityContainer iocContainer,string name)
{
if (iocContainer.IsRegistered<T>(name))
iocContainer.Resolve<T>(name);
iocContainer.ResolveAll<T>();
}
private static void ClearValue<T>(UnityContainer iocContainer, string name)
{
foreach (var registration in iocContainer.Registrations.Where(p => p.RegisteredType == typeof(T)
&& p.Name==name))
{
registration.LifetimeManager.RemoveValue();
}
}
If you debug it, you will see that after the call to ClearValue, the container still says it is registered, but if you try to resolve that instance it will throw an exception. What is even worse, calls to ResolveAll<T> will fail too.
To Sum up, no matter if you do ClearValue, wrap around your register instance with another IoC or a custom class, or provide your own LifeTimeManager, ResolveAll<T> and IsRegistered<T> won´t behave as expected, and the registration will still be there. So don't try it because it won´t work and it will cause problems down the road.
I think that is what you are looking for.
var lifetimeManager = new TransientLifetimeManager();
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance, lifetimeManager);
lifetimeManager.RemoveValue();
Here is how I handled unregistering instances from a unity container
I needed to implement Add/Remove functionality like this:
public interface IObjectBuilder
{
void AddInstance<T>(T instance);
void RemoveInstance<T>(T instance);
}
I created a custom lifetime manager to do the implementation
public class ExplicitLifetimeManager :
LifetimeManager
{
object Value;
public override object GetValue()
{
return Value;
}
public override void SetValue(object newValue)
{
Value = newValue;
}
public override void RemoveValue()
{
Value = null;
}
}
Here is the final implementation:
Dictionary<object, ExplicitLifetimeManager> Instances = new Dictionary<object, ExplicitLifetimeManager>();
public void AddInstance<T>(T instance)
{
ExplicitLifetimeManager e = new ExplicitLifetimeManager();
Instances[instance] = e;
Container.RegisterInstance(instance, e);
}
public void RemoveInstance<T>(T instance)
{
Instances[instance].RemoveValue();
Instances.Remove(instance);
}
calling removevalue on the custom lifetime manager causes the instance to be unregistered
I have the same challenge and after experimenting I solved it by using the standard ContainerControlledLifetimeManager and calling RemoveValue when I want to remove the container instance. Note that if you are not using interfaces and your object has constructor which the container can find and use it will recreate the instance after you have destroyed it with lifetimeManager.RemoveValue().
[TestClass]
public class UnityContainerTest
{
[TestMethod]
public void RemoveFromContainer()
{
UnityContainer container = new UnityContainer();
MyUnityMember member = new MyUnityMember(5);
LifetimeManager lifetimeManager = new ContainerControlledLifetimeManager();
container.RegisterInstance(member, lifetimeManager);
var resolved = container.Resolve<MyUnityMember>();
Assert.IsNotNull(resolved);
lifetimeManager.RemoveValue();
try
{
resolved = container.Resolve<MyUnityMember>();
Assert.Fail(resolved + " is still in the container");
}
catch (ResolutionFailedException)
{
}
}
public class MyUnityMember
{
public MyUnityMember(int x)
{
I = x;
}
public int I { get; private set; }
}
}
I had a similar requirement whereby I wanted to temporarily store objects in the unity container and found this was not possible (or at least easily possible).
If your objective is to have a temporary storage place easily available to unity, then create a temporary storage service.
public class TemporaryStorageService : ITemporaryStorageService
{
public void Deposit<T>(Object o, string key)
{
System.Windows.Application.Current.Properties[key] = o;
}
public T Withdraw<T>(string key)
{ T o = (T)System.Windows.Application.Current.Properties[key];
System.Windows.Application.Current.Properties.Remove(key);
return o;
}
}
Register your service with Unity. Then when you wish to store an object you call the Deposit Method and when you wish to remove the object you call the Withdraw method.
A fuller explanation can be found here

Categories