--- a +++ b/Implementation/APUnitTestFramework/ComponentModelImplementation.cs @@ -0,0 +1,918 @@ +using _3S.CoDeSys.Core.ComponentModel; +using _3S.CoDeSys.Core.Components; +using _3S.CoDeSys.Core.Views; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Xml; + +namespace _3S.APUnitTestFramework +{ + [TypeGuid("{638AA04C-726D-4CD1-99EE-CE402D0DD566}")] + public class ComponentModelImplementation : IComponentModelImplementationForUnitTest + { + public IDependencyResolveContext CreateDependencyResolveContext(Profile profile) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public IEnumerable<IDependency> GetDependencies(Guid plugInGuid, Version version, bool inproc) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public void InjectDependencies(IDependencyInjectable injectable, Type callingType) + { + if (injectable == null) + throw new ArgumentNullException(nameof(injectable)); + if (_dependencyResolver == null) + throw new InvalidOperationException("No dependency resolver has been set."); + + var type = injectable.GetType(); + foreach (var target in _injectionTargetCache.GetInjectionTargets(type)) + { + var value = target.GetInjectionValue(callingType); + value.Prepare(target.Member, _dependencyResolver); + target.Assign(injectable, value); + } + + injectable.InjectionComplete(); + } + + public IDependency LoadDependency(XmlElement element) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public DependencyResolveResult ResolveDependency(SpecificDependency specificDependency, IDependencyResolveContext context) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public DependencyResolveResult ResolveDependency(MultipleDependency multipleDependency, IDependencyResolveContext context) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public DependencyResolveResult ResolveDependency(SingleDependency singleDependency, IDependencyResolveContext context) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public void Save(SpecificDependency specificDependency, XmlElement parentElement) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public void Save(MultipleDependency multipleDependency, XmlElement parentElement) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public void SaveDependency(SingleDependency singleDependency, XmlElement parentElement) + { + // Not required for unit testing. + throw new NotImplementedException(); + } + + public void SetupForUnitTest(Testbed testbed, string profileName, Profile profile) + { + _dependencyResolver = new DependencyResolver(testbed, profileName, profile); + } + + private InjectionTargetCache _injectionTargetCache = new InjectionTargetCache(); + private DependencyResolver _dependencyResolver; + } + + class InjectionTargetCache + { + public IEnumerable<AbstractInjectionTarget> GetInjectionTargets(Type type) + { + IEnumerable<AbstractInjectionTarget> result; + _dictionary.TryGetValue(type, out result); + if (result == null) + { + result = GetInjectionTargetsByReflection(type); + _dictionary[type] = result; + } + return result; + } + + private static IEnumerable<AbstractInjectionTarget> GetInjectionTargetsByReflection(Type type) + { + var result = new List<AbstractInjectionTarget>(); + + IEnumerable<MemberInfo> properties = type.GetProperties(); + IEnumerable<MemberInfo> fields = type.GetFields(); + foreach (var member in Enumerable.Concat(properties, fields)) + { + var target = AbstractInjectionTarget.CreateFromMember(member); + if (target != null) + result.Add(target); + } + + return result; + } + + private Dictionary<Type, IEnumerable<AbstractInjectionTarget>> _dictionary = new Dictionary<Type, IEnumerable<AbstractInjectionTarget>>(); + } + + abstract class AbstractInjectionTarget + { + public MemberInfo Member { get; private set; } + private IInjectionValue _injectionValue; + + protected AbstractInjectionTarget(MemberInfo member) + { + if (member == null) + throw new ArgumentNullException(nameof(member)); + + Member = member; + } + + public static AbstractInjectionTarget CreateFromMember(MemberInfo member) + { + var attr = Attribute.GetCustomAttribute(member, typeof(AbstractInjectAttribute), false); + if (attr == null) + { + return null; + } + else if (attr is InjectSingleInstanceAttribute) + { + var shared = ((InjectSingleInstanceAttribute)attr).Shared; + var optional = ((InjectSingleInstanceAttribute)attr).Optional; + return new SingleInstanceInjectionTarget(shared, optional, member); + } + else if (attr is InjectMultipleInstancesAttribute) + { + var shared = ((InjectMultipleInstancesAttribute)attr).Shared; + var optional = ((InjectMultipleInstancesAttribute)attr).Optional; + return new MultipleInstancesInjectionTarget(shared, optional, member); + } + else if (attr is InjectSpecificInstanceAttribute) + { + var typeGuid = ((InjectSpecificInstanceAttribute)attr).TypeGuid; + var shared = ((InjectSpecificInstanceAttribute)attr).Shared; + var optional = ((InjectSpecificInstanceAttribute)attr).Optional; + return new SpecificInstanceInjectionTarget(typeGuid, shared, optional, member); + } + else if (attr is InjectAnyInstanceAttribute) + { + return new AnyInstanceInjectionTarget(member); + } + else if (attr is InjectSpecificTypeInformationAttribute) + { + var typeGuid = ((InjectSpecificTypeInformationAttribute)attr).TypeGuid; + var optional = ((InjectSpecificTypeInformationAttribute)attr).Optional; + return new SpecificTypeInformationInjectionTarget(typeGuid, optional, member); + } + else if (attr is InjectAnyTypeInformationAttribute) + { + return new AnyTypeInformationInjectionTarget(member); + } + else if (attr is InjectActiveProfileAttribute) + { + return new ActiveProfileInjectionTarget(member); + } + else if (attr is InjectFrameFormAttribute) + { + return new FrameFormInjectionTarget(member); + } + else + { + return null; + } + } + + public IInjectionValue GetInjectionValue(Type callingType) + { + if (_injectionValue == null) + _injectionValue = DoGetInjectionValue(callingType); + + return _injectionValue; + } + + protected abstract IInjectionValue DoGetInjectionValue(Type callingType); + + public void Assign(IDependencyInjectable injectable, IInjectionValue value) + { + var field = Member as FieldInfo; + var property = Member as PropertyInfo; + + if (field != null) + field.SetValue(injectable, value); + else if (property != null) + property.SetValue(injectable, value, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, null, null); + else + Debug.Fail("Injection target must be a field or property."); + } + + protected Type MemberType + { + get + { + var field = Member as FieldInfo; + var property = Member as PropertyInfo; + + if (field != null) + return field.FieldType; + else if (property != null) + return property.PropertyType; + else + return null; + } + } + + protected static bool IsOfGenericType(Type memberType, Type genericType) + { + if (!memberType.IsGenericType) + return false; + else if (!genericType.IsAssignableFrom(memberType.GetGenericTypeDefinition())) + return false; + else + return true; + } + } + + class SingleInstanceInjectionTarget : AbstractInjectionTarget + { + public SingleInstanceInjectionTarget(bool shared, bool optional, MemberInfo member) + : base(member) + { + _shared = shared; + _optional = optional; + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + Type type; + + if (_shared) + { + if (!IsOfGenericType(MemberType, typeof(ISharedSingleInstanceProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(ISharedSingleInstanceProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + type = _optional ? typeof(OptionalSharedSingleInstanceProvider<>).MakeGenericType(contractType) : typeof(SharedSingleInstanceProvider<>).MakeGenericType(contractType); + } + else + { + if (!IsOfGenericType(MemberType, typeof(ISingleInstanceProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(ISingleInstanceProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + type = _optional ? typeof(OptionalSingleInstanceProvider<>).MakeGenericType(contractType) : typeof(SingleInstanceProvider<>).MakeGenericType(contractType); + } + + return (IInjectionValue)Activator.CreateInstance(type); + } + + private bool _shared; + private bool _optional; + } + + class MultipleInstancesInjectionTarget : AbstractInjectionTarget + { + public MultipleInstancesInjectionTarget(bool shared, bool optional, MemberInfo member) + : base(member) + { + _shared = shared; + _optional = optional; + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + Type type; + + if (_shared) + { + if (!IsOfGenericType(MemberType, typeof(ISharedMultipleInstancesProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(ISharedMultipleInstancesProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + type = _optional ? typeof(OptionalSharedMultipleInstancesProvider<>).MakeGenericType(contractType) : typeof(SharedMultipleInstancesProvider<>).MakeGenericType(contractType); + } + else + { + if (!IsOfGenericType(MemberType, typeof(IMultipleInstancesProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(IMultipleInstancesProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + type = _optional ? typeof(OptionalMultipleInstancesProvider<>).MakeGenericType(contractType) : typeof(MultipleInstancesProvider<>).MakeGenericType(contractType); + } + + return (IInjectionValue)Activator.CreateInstance(type); + } + + private bool _shared; + private bool _optional; + } + + class SpecificInstanceInjectionTarget : AbstractInjectionTarget + { + public SpecificInstanceInjectionTarget(Guid typeGuid, bool shared, bool optional, MemberInfo member) + : base(member) + { + _typeGuid = typeGuid; + _shared = shared; + _optional = optional; + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + Type type; + + if (_shared) + { + if (!IsOfGenericType(MemberType, typeof(ISharedSingleInstanceProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(ISharedSingleInstanceProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + type = _optional ? typeof(OptionalSharedSpecificInstanceProvider<>).MakeGenericType(contractType) : typeof(SharedSpecificInstanceProvider<>).MakeGenericType(contractType); + } + else + { + if (!IsOfGenericType(MemberType, typeof(ISingleInstanceProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(ISingleInstanceProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + type = _optional ? typeof(OptionalSpecificInstanceProvider<>).MakeGenericType(contractType) : typeof(SpecificInstanceProviderFallback<>).MakeGenericType(contractType); + } + + var args = new object[] { _typeGuid }; + return (IInjectionValue)Activator.CreateInstance(type, args); + } + + private Guid _typeGuid; + private bool _shared; + private bool _optional; + } + + class AnyInstanceInjectionTarget : AbstractInjectionTarget + { + public AnyInstanceInjectionTarget(MemberInfo member) + : base(member) + { + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + if (!IsOfGenericType(MemberType, typeof(IAnyInstanceProvider<>))) + throw new WrongMemberTypeForInjectionException(Member, typeof(IAnyInstanceProvider<>)); + + var contractType = Enumerable.First(MemberType.GetGenericArguments()); + var type = typeof(AnyInstanceProvider<>).MakeGenericType(contractType); + return (IInjectionValue)Activator.CreateInstance(type); + } + } + + class SpecificTypeInformationInjectionTarget : AbstractInjectionTarget + { + public SpecificTypeInformationInjectionTarget(Guid typeGuid, bool optional, MemberInfo member) + : base(member) + { + _typeGuid = typeGuid; + _optional = optional; + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + if (!typeof(ISpecificTypeInformation).IsAssignableFrom(MemberType)) + throw new WrongMemberTypeForInjectionException(Member, typeof(ISpecificTypeInformation)); + + if (_optional) + return new OptionalSpecificTypeInformation(_typeGuid); + else + return new SpecificTypeInformation(_typeGuid); + } + + private Guid _typeGuid; + private bool _optional; + } + + class AnyTypeInformationInjectionTarget : AbstractInjectionTarget + { + public AnyTypeInformationInjectionTarget(MemberInfo member) + : base(member) + { + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + if (!typeof(IAnyTypeInformation).IsAssignableFrom(MemberType)) + throw new WrongMemberTypeForInjectionException(Member, typeof(IAnyTypeInformation)); + + return new AnyTypeInformation(); + } + } + + class ActiveProfileInjectionTarget : AbstractInjectionTarget + { + public ActiveProfileInjectionTarget(MemberInfo member) + : base(member) + { + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + if (!typeof(IProfileInformation).IsAssignableFrom(MemberType)) + throw new WrongMemberTypeForInjectionException(Member, typeof(IProfileInformation)); + + return new ProfileInformation(); + } + } + + class FrameFormInjectionTarget : AbstractInjectionTarget + { + public FrameFormInjectionTarget(MemberInfo member) + : base(member) + { + } + + protected override IInjectionValue DoGetInjectionValue(Type callingType) + { + if (!typeof(IWinFormWrapperProxy).IsAssignableFrom(MemberType)) + throw new WrongMemberTypeForInjectionException(Member, typeof(IWinFormWrapperProxy)); + + return new WinFormWrapperProxy(); + } + } + + interface IInjectionValue + { + void Prepare(MemberInfo member, DependencyResolver dependencyResolver); + } + + abstract class AbstractSingleInstanceProvider<TContract> : IInjectionValue where TContract : class + { + public abstract void Prepare(MemberInfo member, DependencyResolver dependencyResolver); + + public Guid TypeGuid + { + get { return _valueProvider.TypeGuid; } + } + + protected void DoPrepare(MemberInfo member, bool optional, DependencyResolver dependencyResolver) + { + if (dependencyResolver == null) + throw new ArgumentNullException(nameof(dependencyResolver)); + + _valueProvider = dependencyResolver.ResolveSingle(typeof(TContract), optional, member); + } + + protected TContract DoCreate() + { + return _valueProvider.CreateInstance<TContract>(); + } + + private IValueProvider _valueProvider; + } + + abstract class AbstractSharedSingleInstanceProvider<TContract> : AbstractSingleInstanceProvider<TContract>, ISharedSingleInstanceProvider<TContract> where TContract : class + { + public TContract Value + { + get + { + if (!_valueCreated) + { + _value = DoCreate(); + _valueCreated = true; + } + return _value; + } + } + + private TContract _value; + private bool _valueCreated; + } + + class SingleInstanceProvider<TContract> : AbstractSingleInstanceProvider<TContract>, ISingleInstanceProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + + public TContract Create() + { + return DoCreate(); + } + } + + class OptionalSingleInstanceProvider<TContract> : AbstractSingleInstanceProvider<TContract>, ISingleInstanceProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + + public TContract Create() + { + return DoCreate(); + } + } + + class SharedSingleInstanceProvider<TContract> : AbstractSharedSingleInstanceProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + } + + class OptionalSharedSingleInstanceProvider<TContract> : AbstractSharedSingleInstanceProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + } + + abstract class AbstractMultipleInstancesProvider<TContract> : IInjectionValue where TContract : class + { + public abstract void Prepare(MemberInfo member, DependencyResolver depencencyResolver); + + public IEnumerable<Guid> TypeGuids + { + get { return _valueProviders.Select(vp => vp.TypeGuid); } + } + + protected void DoPrepare(MemberInfo member, bool optional, DependencyResolver dependencyResolver) + { + if (dependencyResolver == null) + throw new ArgumentNullException(nameof(dependencyResolver)); + + _valueProviders = dependencyResolver.ResolveMultiple(typeof(TContract), optional, member); + } + + protected IEnumerable<TContract> DoCreate() + { + return _valueProviders.Select(vp => vp.CreateInstance<TContract>()); + } + + private IEnumerable<IValueProvider> _valueProviders; + } + + abstract class AbstractSharedMultipleInstancesProvider<TContract> : AbstractMultipleInstancesProvider<TContract>, ISharedMultipleInstancesProvider<TContract> where TContract : class + { + public IEnumerable<TContract> Value + { + get + { + if (!_valueCreated) + { + _value = Enumerable.ToList(DoCreate()); + _valueCreated = true; + } + return _value; + } + } + + private List<TContract> _value; + private bool _valueCreated; + } + + class MultipleInstancesProvider<TContract> : AbstractMultipleInstancesProvider<TContract>, IMultipleInstancesProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + + public IEnumerable<TContract> Create() + { + return Enumerable.ToList(DoCreate()); // If we would not call ToList(), every iteration over the enumerable would create new objects, which is likely not expected by the caller. + } + + public TContract CreateFirst() + { + return Enumerable.First(DoCreate()); + } + } + + class OptionalMultipleInstancesProvider<TContract> : AbstractMultipleInstancesProvider<TContract>, IMultipleInstancesProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + + public IEnumerable<TContract> Create() + { + return Enumerable.ToList(DoCreate()); // If we would not call ToList(), every iteration over the enumerable would create new objects, which is likely not expected by the caller. + } + + public TContract CreateFirst() + { + return Enumerable.FirstOrDefault(DoCreate()); + } + } + + class SharedMultipleInstancesProvider<TContract> : AbstractSharedMultipleInstancesProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + } + + class OptionalSharedMultipleInstancesProvider<TContract> : AbstractSharedMultipleInstancesProvider<TContract> where TContract : class + { + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + } + + abstract class AbstractSpecificInstanceProvider<TContract> : IInjectionValue where TContract : class + { + protected AbstractSpecificInstanceProvider(Guid typeGuid) + { + _typeGuid = typeGuid; + } + + public Guid TypeGuid + { + get { return _valueProvider.TypeGuid; } + } + + public abstract void Prepare(MemberInfo member, DependencyResolver depencencyResolver); + + protected void DoPrepare(MemberInfo member, bool optional, DependencyResolver dependencyResolver) + { + if (dependencyResolver == null) + throw new ArgumentNullException(nameof(dependencyResolver)); + + _valueProvider = dependencyResolver.ResolveSpecific(_typeGuid, typeof(TContract), optional, member); + } + + protected TContract DoCreate() + { + return _valueProvider.CreateInstance<TContract>(); + } + + private Guid _typeGuid; + private IValueProvider _valueProvider; + } + + abstract class AbstractSharedSpecificInstanceProvider<TContract> : AbstractSpecificInstanceProvider<TContract>, ISharedSingleInstanceProvider<TContract> where TContract : class + { + protected AbstractSharedSpecificInstanceProvider(Guid typeGuid) + : base(typeGuid) + { + } + + public TContract Value + { + get + { + if (!_valueCreated) + { + _value = DoCreate(); + _valueCreated = true; + } + return _value; + } + } + + private TContract _value; + private bool _valueCreated; + } + + class SpecificInstanceProviderFallback<TContract> : AbstractSpecificInstanceProvider<TContract>, ISingleInstanceProvider<TContract> where TContract : class + { + public SpecificInstanceProviderFallback(Guid typeGuid) + : base(typeGuid) + { + } + + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + + public TContract Create() + { + return DoCreate(); + } + } + + class OptionalSpecificInstanceProvider<TContract> : AbstractSpecificInstanceProvider<TContract>, ISingleInstanceProvider<TContract> where TContract : class + { + public OptionalSpecificInstanceProvider(Guid typeGuid) + : base(typeGuid) + { + } + + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + + public TContract Create() + { + return DoCreate(); + } + } + + class SharedSpecificInstanceProvider<TContract> : AbstractSharedSpecificInstanceProvider<TContract> where TContract : class + { + public SharedSpecificInstanceProvider(Guid typeGuid) + : base(typeGuid) + { + } + + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + } + + class OptionalSharedSpecificInstanceProvider<TContract> : AbstractSharedSpecificInstanceProvider<TContract> where TContract : class + { + public OptionalSharedSpecificInstanceProvider(Guid typeGuid) + : base(typeGuid) + { + } + + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + } + + class AnyInstanceProvider<TContract> : IAnyInstanceProvider<TContract>, IInjectionValue where TContract : class + { + public void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + _member = member; + _dependencyResolver = depencencyResolver; + } + + public TContract Create(Guid typeGuid) + { + if (_dependencyResolver == null) + throw new InvalidOperationException("The dependency resolver has not been set."); + + return _dependencyResolver.ResolveSpecific(typeGuid, typeof(TContract), false, _member).CreateInstance<TContract>(); + } + + public TContract TryCreate(Guid typeGuid) + { + if (_dependencyResolver == null) + throw new InvalidOperationException("The dependency resolver has not been set."); + + return _dependencyResolver.ResolveSpecific(typeGuid, typeof(TContract), true, _member).CreateInstance<TContract>(); + } + + private MemberInfo _member; + private DependencyResolver _dependencyResolver; + } + + abstract class AbstractSpecificTypeInformation : ISpecificTypeInformation, IInjectionValue + { + protected AbstractSpecificTypeInformation(Guid typeGuid) + { + TypeGuid = typeGuid; + } + + public abstract void Prepare(MemberInfo member, DependencyResolver depencencyResolver); + + public Guid TypeGuid { get; private set; } + + public Type Type { get; private set; } + public TypeInformation TypeInformation { get; private set; } + + protected void DoPrepare(MemberInfo member, bool optional, DependencyResolver dependencyResolver) + { + if (dependencyResolver == null) + throw new ArgumentNullException(nameof(dependencyResolver)); + + try + { + var valueProvider = dependencyResolver.ResolveSpecific(TypeGuid, typeof(object), optional, member); + Type = valueProvider.Type; + TypeInformation = valueProvider.TypeInformation; + } + catch (NoInstanceForInjectionException ex) + { + // It is inconsistent compared to other injection to throw the exception + // immediately within the DoPrepare() method (instead upon value retrieval by the + // consumer), but the original implementation behaves likewise. + throw new NoTypeInformationForInjectionException(ex.InjectionTarget); + } + } + } + + class SpecificTypeInformation : AbstractSpecificTypeInformation + { + public SpecificTypeInformation(Guid typeGuid) + : base(typeGuid) + { + } + + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, false, depencencyResolver); + } + } + + class OptionalSpecificTypeInformation : AbstractSpecificTypeInformation + { + public OptionalSpecificTypeInformation(Guid typeGuid) + : base(typeGuid) + { + } + + public override void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + DoPrepare(member, true, depencencyResolver); + } + } + + class AnyTypeInformation : IAnyTypeInformation, IInjectionValue + { + public void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + _member = member; + _dependencyResolver = depencencyResolver; + } + + public Type GetType(Guid typeGuid) + { + if (_dependencyResolver == null) + throw new ArgumentNullException(nameof(_dependencyResolver)); + + return _dependencyResolver.ResolveSpecific(typeGuid, typeof(object), false, _member).Type; + } + + public Type TryGetType(Guid typeGuid) + { + if (_dependencyResolver == null) + throw new ArgumentNullException(nameof(_dependencyResolver)); + + return _dependencyResolver.ResolveSpecific(typeGuid, typeof(object), true, _member).Type; + } + + public TypeInformation GetTypeInformation(Guid typeGuid) + { + if (_dependencyResolver == null) + throw new ArgumentNullException(nameof(_dependencyResolver)); + + return _dependencyResolver.ResolveSpecific(typeGuid, typeof(object), false, _member).TypeInformation; + } + + public TypeInformation TryGetTypeInformation(Guid typeGuid) + { + if (_dependencyResolver == null) + throw new ArgumentNullException(nameof(_dependencyResolver)); + + return _dependencyResolver.ResolveSpecific(typeGuid, typeof(object), true, _member).TypeInformation; + } + + private MemberInfo _member; + private DependencyResolver _dependencyResolver; + } + + class ProfileInformation : IProfileInformation, IInjectionValue + { + public void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + if (depencencyResolver == null) + throw new ArgumentNullException(nameof(depencencyResolver)); + + string profileName; + Profile profile; + depencencyResolver.ResolveProfile(member, out profileName, out profile); + ProfileName = profileName; + Profile = profile; + } + + public string ProfileName { get; private set; } + public Profile Profile { get; private set; } + } + + class WinFormWrapperProxy : IWinFormWrapperProxy, IInjectionValue + { + public IWinFormWrapper FrameForm { get; private set; } + + public void Prepare(MemberInfo member, DependencyResolver depencencyResolver) + { + if (depencencyResolver == null) + throw new ArgumentNullException(nameof(depencencyResolver)); + + FrameForm = depencencyResolver.ResolveFrameForm(member); + } + } +}