Skip to content

5.2.1.235

Compare
Choose a tag to compare
@ENikS ENikS released this 15 Nov 00:56

Bug Fix

This release is a part of a fix of longest running Unity bug (almost a feature now). The problem it addresses is with registrations affecting each other when new registration is the same Type as previously registered mapping.
Following code explains the problem:

IUnityContainer uc = new UnityContainer();

uc.RegisterType<ILogger, MockLogger>(new ContainerControlledLifetimeManager());
ILogger logger = uc.Resolve<ILogger>();

Assert.IsNotNull(logger);
Assert.AreSame(uc.Resolve<ILogger>(), logger); <-- Resolves Singleton as it should

uc.RegisterType<MockLogger>(new TransientLifetimeManager()); <-- Here is the problem

Assert.AreSame(uc.Resolve<ILogger>(), logger); <-- Resolves new MockLogger and fails

The issue is described here

Impact on existing code

To demonstrate impact on existing code please look at this example:

container.RegisterType<ISomething, Something>(new ContainerControlledLifetimeManager());

var a = container.Resolve<Something>();
var b = container.Resolve<ISomething>();

Assert.AreNotSame(a, b);

Due to the this bug resolving a and b returned the same result because ContainerControlledLifetimeManager would be applied to ToType instead of FromType as it should. In other words it would be applied to Something instead of ISomething.

This fix corrects this behavior so only ISomething (FromType) registers with ContainerControlledLifetimeManager and resolution of Something type will use transient manager.

You could revert back to previous Unity behavior (before this bug fix) by simply registering mapped type with proper lifetime manager:

container.RegisterType<Something>(new ContainerControlledLifetimeManager());

For more information see: #35, 163, #164, #165, #170, #177

More strict use of InjectionFactory

This form of registration used to work for registering interface with InjectionFactory but it is no longer allowed.

RegisterType<IService, Service>(new InjectionFactory(c => new Service()));

As written, this code registers both: a mapping between IService and Service and between IService and InjectionFactory. These two are mutually exclusive and create ambiguity which Unity can not resolve.
It should be either one of these but not both:

RegisterType<IService, Service>();
RegisterType<IService>(new InjectionFactory(c => new Service()));

For more information see: #38