/// <summary> /// Gets the contributors for generating the type definition. /// </summary> /// <param name="interfaces">Additional interfaces to implement.</param> /// <param name="proxyTargetType">The target type for the proxy.</param> /// <param name="contributors">The list of contributors that will be used to generate the type.</param> /// <param name="namingScope">The proxy type naming scope.</param> /// <returns> /// The list of types being implemented. /// </returns> /// <remarks> /// <para> /// This version of the method basically does the same thing as the /// original/base implementation but with these key differences: /// </para> /// <list type="bullet"> /// <item> /// <term>No mixin support</term> /// <description> /// The original version of the method looks at the <see cref="Castle.DynamicProxy.Generators.BaseProxyGenerator.ProxyGenerationOptions"/> /// to see if there are any mixins to be added to the generated proxy. /// There is no need for mixin support in WCF service hosting so mixins /// aren't even checked for and won't be added. /// </description> /// </item> /// <item> /// <term>No additional interfaces</term> /// <description> /// The original version of the method goes through each of the additional /// interfaces that the are to be implemented, checks them against collisions /// with mixin definitions, and adds type mappings for the additional interfaces. /// The only interface that needs to be implemented for the WCF hosting /// proxy is the service interface, so all of that additional interface /// checking is skipped. /// </description> /// </item> /// <item> /// <term>Custom instance contributor used</term> /// <description> /// The original version of the method uses the /// <see cref="Castle.DynamicProxy.Contributors.InterfaceProxyInstanceContributor"/> /// as the code generator for the proxy type. Unfortunately, that contributor /// copies over all non-inherited attributes on the interface including /// the <see cref="System.ServiceModel.ServiceContractAttribute"/>. The /// concrete proxy type can't have that attribute because the interface /// already has it, so WCF hosting dies. This version of the method uses /// the <see cref="Autofac.Extras.Multitenant.Wcf.DynamicProxy.IgnoreAttributeInterfaceProxyInstanceContributor"/> /// which does not copy over non-inherited attributes. /// </description> /// </item> /// </list> /// </remarks> /// <seealso cref="Autofac.Extras.Multitenant.Wcf.DynamicProxy.IgnoreAttributeInterfaceProxyInstanceContributor"/> protected override IEnumerable <Type> GetTypeImplementerMapping(Type[] interfaces, Type proxyTargetType, out IEnumerable <ITypeContributor> contributors, INamingScope namingScope) { var typeImplementerMapping = new Dictionary <Type, ITypeContributor>(); var allInterfaces = TypeUtil.GetAllInterfaces(new[] { proxyTargetType }); var additionalInterfaces = TypeUtil.GetAllInterfaces(interfaces); var implementer = AddMappingForTargetType(typeImplementerMapping, proxyTargetType, allInterfaces, additionalInterfaces, namingScope); var instance = new IgnoreAttributeInterfaceProxyInstanceContributor(targetType, GeneratorType, interfaces); AddMappingForISerializable(typeImplementerMapping, instance); try { AddMappingNoCheck(typeof(IProxyTargetAccessor), instance, typeImplementerMapping); } catch (ArgumentException) { HandleExplicitlyPassedProxyTargetAccessor(allInterfaces, additionalInterfaces); } contributors = new List <ITypeContributor> { implementer, instance }; return(typeImplementerMapping.Keys); }
/// <summary> /// Gets the contributors for generating the type definition. /// </summary> /// <param name="interfaces">Additional interfaces to implement.</param> /// <param name="proxyTargetType">The target type for the proxy.</param> /// <param name="contributors">The list of contributors that will be used to generate the type.</param> /// <param name="namingScope">The proxy type naming scope.</param> /// <returns> /// The list of types being implemented. /// </returns> /// <remarks> /// <para> /// This version of the method basically does the same thing as the /// original/base implementation but with these key differences: /// </para> /// <list type="bullet"> /// <item> /// <term>No mixin support</term> /// <description> /// The original version of the method looks at the <see cref="Castle.DynamicProxy.Generators.BaseProxyGenerator.ProxyGenerationOptions"/> /// to see if there are any mixins to be added to the generated proxy. /// There is no need for mixin support in WCF service hosting so mixins /// aren't even checked for and won't be added. /// </description> /// </item> /// <item> /// <term>No additional interfaces</term> /// <description> /// The original version of the method goes through each of the additional /// interfaces that the are to be implemented, checks them against collisions /// with mixin definitions, and adds type mappings for the additional interfaces. /// The only interface that needs to be implemented for the WCF hosting /// proxy is the service interface, so all of that additional interface /// checking is skipped. /// </description> /// </item> /// <item> /// <term>Custom instance contributor used</term> /// <description> /// The original version of the method uses the /// <see cref="Castle.DynamicProxy.Contributors.InterfaceProxyInstanceContributor"/> /// as the code generator for the proxy type. Unfortunately, that contributor /// copies over all non-inherited attributes on the interface including /// the <see cref="System.ServiceModel.ServiceContractAttribute"/>. The /// concrete proxy type can't have that attribute because the interface /// already has it, so WCF hosting dies. This version of the method uses /// the <see cref="Autofac.Extras.Multitenant.Wcf.DynamicProxy.IgnoreAttributeInterfaceProxyInstanceContributor"/> /// which does not copy over non-inherited attributes. /// </description> /// </item> /// </list> /// </remarks> /// <seealso cref="Autofac.Extras.Multitenant.Wcf.DynamicProxy.IgnoreAttributeInterfaceProxyInstanceContributor"/> protected override IEnumerable<Type> GetTypeImplementerMapping(Type[] interfaces, Type proxyTargetType, out IEnumerable<ITypeContributor> contributors, INamingScope namingScope) { var typeImplementerMapping = new Dictionary<Type, ITypeContributor>(); var allInterfaces = TypeUtil.GetAllInterfaces(new[] { proxyTargetType }); var additionalInterfaces = TypeUtil.GetAllInterfaces(interfaces); var implementer = AddMappingForTargetType(typeImplementerMapping, proxyTargetType, allInterfaces, additionalInterfaces, namingScope); var instance = new IgnoreAttributeInterfaceProxyInstanceContributor(targetType, GeneratorType, interfaces); AddMappingForISerializable(typeImplementerMapping, instance); try { AddMappingNoCheck(typeof(IProxyTargetAccessor), instance, typeImplementerMapping); } catch (ArgumentException) { HandleExplicitlyPassedProxyTargetAccessor(allInterfaces, additionalInterfaces); } contributors = new List<ITypeContributor> { implementer, instance }; return typeImplementerMapping.Keys; }