Injecting registration contexts into resolved objects

Apr 14, 2012 at 9:27 PM

I need to inject the context used for registering a specific type into the resolved object(s).

For example:

 _unityContainer.RegisterType<ITestViewModel, TestViewModel>("TestContext");

  var viewModel = _unityContainer.Resolve<ITestViewModel>("TestContext");

The ITestViewModel interface has an object VmContext property - I need to set this property with the "TestContext" context value when the object is being built by Unity.

What is the best way to do this? I'm currently looking at creating a Unity build extension as a possible solution, but I'm just getting started with it.

Apr 14, 2012 at 10:46 PM

Ok I've figured it out.  I did need a custom Unity extension and builder strategy:

    /// <summary>
    /// The Unity extension for injecting the registration context into the resolved objects.
    /// </summary>
    public class ContextInjectionUnityExtension : UnityContainerExtension
    {
        /// <summary>
        /// Add the registration context injection builder strategy to the list of builder strategies.
        /// </summary>
        protected override void Initialize()
        {
            this.Context.Strategies.Add(new ContextInjectionUnityBuilderStrategy(), UnityBuildStage.PostInitialization);
        }
    }

    /// <summary>
    /// The Unity builder strategy for injecting the registration context into the resolved objects.
    /// </summary>
    public class ContextInjectionUnityBuilderStrategy : BuilderStrategy
    {
        /// <summary>
        /// Attempt to inject the registration context after the object has been built.
        /// </summary>
        /// <param name="context">The builder context.</param>
        public override void PostBuildUp(IBuilderContext context)
        {
            if (context.OriginalBuildKey.Name != null)
                foreach (RegistrationContextPropertyNames propertyName in Enum.GetValues(typeof(RegistrationContextPropertyNames)))
                {
                    PropertyInfo propertyInfo = context.Existing.GetType().GetProperty(propertyName.ToString());

                    if (propertyInfo != null)
                        propertyInfo.SetValue(context.Existing, context.OriginalBuildKey.Name, null);
                }
        }

    /// <summary>
    /// Enumeration for the different registration context property names.
    /// </summary>
    public enum RegistrationContextPropertyNames
    {
        VmContext
    }