我在SL版本2.5.1.0中使用Castle。我有代理内部类(当然,接口是公共的,但是实现是内部的,因此使用者只知道接口)。
我在程序集中使用以下属性和内部类
[assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("Castle.Windsor, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]在完全.NET 4.0模式下,使用.NET 4.0城堡程序集,这很好,并且我的类型被代理为OK。在Silverlight,在Silverlight城堡集会中,我得到:
Type ConsoleApplication4.MyTypeToBeProxied is not public. Can not create proxy for types that are not accessible.此外,仅在疑难解答问题时,添加以下内容似乎没有什么区别.:
[assembly: InternalsVisibleTo("System.Core, PublicKey=00000000000000000400000000000000")]
[assembly: InternalsVisibleTo("System.Core, PublicKey=" +
"00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649" +
"383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb7" +
"7e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638" +
"fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c" +
"123b37ab")]我还在运行时验证了SL中动态承载的程序集的名称实际上仍然是DynamicProxyGenAssembly2。
有什么想法吗?谢谢。
编辑
我发现了我认为的问题:
.NET 4.0的城堡有:
private bool IsAccessible(Type target)
{
// ....
return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy);
}在DefaultProxyBuilder...and SL 4中有
private bool IsAccessible(Type target)
{
target.IsNested();
return (target.IsPublic || target.IsNestedPublic);
}这是可以在城堡源中修复的东西吗?或者我需要/应该将DefaultProxyFactory子类化吗?
发布于 2010-11-17 01:11:11
这件事我运气不错。老实说,我不知道为什么,但我不能重现Krzysztof描述的问题。我的suspect...maybe...it与以下事实有关:我的程序集是SN.这需要我做一个额外的change...but,这样我就能够在SL测试应用程序中为内部类(具有公共接口)解析代理。
我必须对Castle.Core源代码所做的唯一更改是使字段ModuleScope.moduleBuilder和ModuleScope.moduleBuilderWithStrongName受到保护,而不是私有。但是,这仍然是必要的,这样我就可以在SL中定义SN'd动态程序集了,它是由ModuleScope在Castle.Core中禁用的。现在,我有了一个定制的ModuleScope,如下所示:
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;
}
}还有一个定制的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);
}
}还有一个定制的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());
}
}以及容器设置:
container = new WindsorContainer();
container.Kernel.ProxyFactory = new DefaultProxyFactory();我不太喜欢修改Castle.Core源代码,所以我真的很想听听您的想法--如果这个解决方案不适用于其他测试用例,那么Krzysztof...maybe --您能让这些字段受到保护吗?
发布于 2010-11-11 17:41:48
我可能完全不在这里,但你不是在找IncludeNonPublicTypes()**?** 吗?
从文件中
注册非公共类型 默认情况下,只有程序集外部可见的类型才会注册。如果要包括非公共类型,则必须首先指定程序集,然后调用IncludeNonPublicTypes。
container.Register(
AllTypes.FromThisAssembly()
.IncludeNonPublicTypes()
.BasedOn<NonPublicComponent>()
);发布于 2010-11-11 21:52:47
原因是Silverlight安全模型不允许我们为内部类型构建代理,即使使用InternalsVisibleTo。
https://stackoverflow.com/questions/4156499
复制相似问题