Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Microsoft.Practices.ObjectBuilder2;
- using Microsoft.Practices.Unity;
- using Microsoft.Practices.Unity.ObjectBuilder;
- namespace ConsoleApplication1
- {
- internal class DefaultCtorExtension : UnityContainerExtension
- {
- protected override void Initialize()
- {
- Context.Policies.Set(typeof(IConstructorSelectorPolicy), new DefaultConstructorSelectorPolicy(), "DefaultCtor");
- }
- }
- public class DefaultConstructorSelectorPolicy : DefaultConstructorPolicyBase<InjectionConstructorAttribute>
- {
- protected override IDependencyResolverPolicy CreateResolver(ParameterInfo param)
- {
- IEnumerable<DependencyResolutionAttribute> attributes = param.GetCustomAttributes(false).Cast<DependencyResolutionAttribute>();
- // Resolve all DependencyAttributes on this parameter, if any
- List<DependencyResolutionAttribute> attrs = new List<DependencyResolutionAttribute>(attributes);
- if(attrs.Count > 0)
- {
- // Since this attribute is defined with MultipleUse = false, the compiler will
- // enforce at most one. So we don't need to check for more.
- return attrs[0].CreateResolver(param.ParameterType);
- }
- // No attribute, just go back to the container for the default for that type.
- return new NamedTypeDependencyResolverPolicy(param.ParameterType, null);
- }
- }
- public abstract class DefaultConstructorPolicyBase<TInjectionConstructorMarkerAttribute>
- : IConstructorSelectorPolicy
- where TInjectionConstructorMarkerAttribute : Attribute
- {
- public SelectedConstructor SelectConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination)
- {
- Type typeToConstruct = context.BuildKey.Type;
- ConstructorInfo ctor = FindInjectionConstructor(typeToConstruct) ?? GetDefaultConstructor(typeToConstruct);
- SelectedConstructor result = null;
- if(ctor != null)
- result = CreateSelectedConstructor(context, ctor);
- return result;
- }
- private SelectedConstructor CreateSelectedConstructor(IBuilderContext context, ConstructorInfo ctor)
- {
- SelectedConstructor result = new SelectedConstructor(ctor);
- foreach(ParameterInfo param in ctor.GetParameters())
- {
- string key = Guid.NewGuid().ToString();
- IDependencyResolverPolicy policy = CreateResolver(param);
- context.PersistentPolicies.Set(policy, key);
- DependencyResolverTrackerPolicy.TrackKey(context.PersistentPolicies, context.BuildKey, key);
- result.AddParameterKey(key);
- }
- return result;
- }
- protected abstract IDependencyResolverPolicy CreateResolver(ParameterInfo param);
- private static ConstructorInfo FindInjectionConstructor(Type typeToConstruct)
- {
- ConstructorInfo[] injectionConstructors = typeToConstruct.GetConstructors()
- .Where(ctor => ctor.IsDefined(typeof(TInjectionConstructorMarkerAttribute), true))
- .ToArray();
- ConstructorInfo result = null;
- switch(injectionConstructors.Length)
- {
- case 0:
- result = null;
- break;
- case 1:
- result = injectionConstructors[0];
- break;
- default:
- string msg = string.Format("The type {0} has multiple constructors marked with the InjectionConstructor attribute. Unable to disambiguate.", typeToConstruct.Name);
- throw new InvalidOperationException(msg);
- }
- return result;
- }
- private static ConstructorInfo GetDefaultConstructor(Type typeToConstruct)
- {
- ConstructorInfo[] constructors = typeToConstruct.GetConstructors();
- Array.Sort(constructors, new ConstructorLengthComparer());
- ConstructorInfo result = null;
- switch(constructors.Length)
- {
- case 0:
- result = null;
- break;
- case 1:
- result = constructors[0];
- break;
- default:
- int paramLength = constructors[0].GetParameters().Length;
- if(constructors[1].GetParameters().Length == paramLength)
- {
- string msg = string.Format("The type {0} has multiple constructors of length {1}. Unable to disambiguate.", typeToConstruct.Name, paramLength);
- throw new InvalidOperationException(msg);
- }
- result = constructors[0];
- break;
- }
- return result;
- }
- private class ConstructorLengthComparer : IComparer<ConstructorInfo>
- {
- public int Compare(ConstructorInfo x, ConstructorInfo y)
- {
- return x.GetParameters().Length - y.GetParameters().Length;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement