Castle Windsor InternalsVisibleTo Silverlight

北慕城南 提交于 2019-12-05 04:50:38

I had some luck with this. To be honest, I'm not sure why, but I couldn't reproduce the problem described by Krzysztof. I suspect...maybe...it has something to do with the fact that my assemblies are SN'd...which required me to make an additional change...but once I did, I was able to get proxies resolved for internal classes (with public interfaces) in a SL test application.

The only change I had to make to the Castle.Core source was to make the fields ModuleScope.moduleBuilder and ModuleScope.moduleBuilderWithStrongName protected instead of private. But again, that was only necessary so that I could define a SN'd dynamic assembly in SL, which is disabled for SL by the ModuleScope in Castle.Core. So, now I have a custom ModuleScope as follows:

    private class StrongNameModuleScope : ModuleScope
    {
        public StrongNameModuleScope()
        {
            var assemblyName = new AssemblyName("DynamicProxyGenAssembly2");
            // copied from another one of my SN assemblies (plus GetName() on assembly is security critical so I can't pull it off the executing assembly)
            byte[] publicKey = Convert.FromBase64String(@"ACQAAASAAACUAAAABgIAAAAkAABSU0ExAAQAAAEAAQBvwWquPXQG9zfemS8uDsFdGDScOCSjZ9aFsQDtrrAqKzvlxEGMz3t9Q9M3X9NKqy1ouLZi+sX8yVDafX+UnygFWWfOBosw9nGwG61MTKEhEjdKH0rECahGIXY+ETdNY64HduuH/BIbEs/RDhrrH2hiqGrOGb6AghD1sZ6g0A1qkg==");
            assemblyName.SetPublicKey(publicKey);
            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder module = assembly.DefineDynamicModule("DynamicProxyGenAssembly2");
            moduleBuilder = module;
            moduleBuilderWithStrongName = module;
        }
    }

And a custom DefaultProxyBuilder:

    /// <summary>
    ///   A custom IProxyBuilder copies from the full .NET Castle implementation that allows for proxies of internal types where the InternalsVisibleToAttribute is applied.
    /// </summary>
    private class DefaultProxyBuilder : IProxyBuilder
    {
       ...
        // Methods
        public DefaultProxyBuilder()
            : this(new StrongNameModuleScope())
        {
        }
       ...
        private static bool IsAccessible(Type target)
        {
            bool isTargetNested = target.IsNested;
            bool isNestedAndInternal = isTargetNested && (target.IsNestedAssembly || target.IsNestedFamORAssem);
            bool internalAndVisibleToDynProxy = ((!target.IsVisible && !isTargetNested) || isNestedAndInternal) && InternalsHelper.IsInternalToDynamicProxy(target.Assembly);
            return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy);
        }
    }

And a custom DefaultProxyFactory:

  /// <summary>
    ///   A simple DefaultProxyFactory to wrap the modified DefaultProxyBuilder.
    /// </summary>
    private class DefaultProxyFactory : global::Castle.Windsor.Proxy.DefaultProxyFactory
    {
        public DefaultProxyFactory()
        {
            generator = new ProxyGenerator(new DefaultProxyBuilder());
        }
    }

And the container setup:

        container = new WindsorContainer();

        container.Kernel.ProxyFactory = new DefaultProxyFactory();

I'm not so fond of having had to modify the Castle.Core sources, so I'd really like to hear your thoughts Krzysztof...maybe could you just make those fields protected if this solution doesn't work for other test cases?

I may be totally off base here, but aren't you looking for IncludeNonPublicTypes()?

From the documentation:

Registering non-public types

By default only types visible from outside of the assembly will be registered. If you want to include non-public types, you have to start with specifying assembly first, and then call IncludeNonPublicTypes

container.Register(
    AllTypes.FromThisAssembly()
        .IncludeNonPublicTypes()
        .BasedOn<NonPublicComponent>()
);

The reason for that is that Silverlight security model does not allow us to build a proxy for an internal type, even with InternalsVisibleTo.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!