2010-11-11 29 views
7

Tôi đang sử dụng Castle Windsor cho SL v2.5.1.0. Tôi có nó lớp proxy bên trong (các giao diện được công khai tất nhiên, nhưng việc thực hiện là nội bộ, để người tiêu dùng chỉ nhận thức được giao diện).Castle Windsor InternalsVisibleTo Silverlight

Tôi đang sử dụng các thuộc tính sau trong lắp ráp của tôi với các lớp nội

[assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")] 
[assembly: InternalsVisibleTo("Castle.Windsor, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")] 
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 

Trong chế độ toàn .NET 4.0, với .NET 4.0 lắp ráp Lâu đài, điều này hoạt động tốt và các loại tôi đang proxy OK. Trong Silverlight, với các hội đồng Silverlight Castle, tôi nhận được: dường như

Type ConsoleApplication4.MyTypeToBeProxied is not public. Can not create proxy for types that are not accessible. 

Ngoài ra, chỉ trong xử lý sự cố các vấn đề, thêm dòng sau vào làm cho không có sự khác biệt ...:

[assembly: InternalsVisibleTo("System.Core, PublicKey=00000000000000000400000000000000")] 
[assembly: InternalsVisibleTo("System.Core, PublicKey=" + 
"00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649" + 
"383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb7" + 
"7e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638" + 
"fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c" + 
"123b37ab")] 

và tôi đã cũng được xác minh tại thời điểm chạy mà tên của hội đồng được lưu trữ động trong SL vẫn còn trong thực tế DynamicProxyGenAssembly2.

Bất kỳ ý tưởng nào? Cảm ơn.

EDIT:

tôi thấy vấn đề tôi nghĩ:

Castle cho .NET 4.0 có:

private bool IsAccessible(Type target) 
{ 
    //  .... 
    return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy); 

} 

trong DefaultProxyBuilder ... và SL 4 có

private bool IsAccessible(Type target) 
{ 
    target.IsNested(); 
    return (target.IsPublic || target.IsNestedPublic); 
} 

Đây có phải là thứ có thể được khắc phục trong C astle source? Hoặc tôi cần phải/tôi nên sub-class DefaultProxyFactory?

Trả lời

2

Tôi đã có một số may mắn với điều này. Thành thật mà nói, tôi không chắc chắn tại sao, nhưng tôi không thể tái tạo vấn đề được mô tả bởi Krzysztof. Tôi nghi ngờ ... có lẽ ... nó có liên quan đến thực tế là hội đồng của tôi là SN'd ... yêu cầu tôi phải thay đổi thêm ... nhưng một khi tôi đã làm, tôi đã có thể nhận được proxy giải quyết cho các lớp bên trong (với các giao diện công cộng) trong một ứng dụng thử nghiệm SL.

Sự thay đổi duy nhất tôi phải thực hiện cho Castle.Core nguồn là làm cho các trường ModuleScope.moduleBuilderModuleScope.moduleBuilderWithStrongName được bảo vệ thay vì riêng tư.Nhưng một lần nữa, đó là chỉ cần thiết để tôi có thể xác định một hội động SN'd trong SL, được vô hiệu hóa cho SL bởi ModuleScope trong Castle.Core. Vì vậy, bây giờ tôi có một ModuleScope tùy chỉnh như sau:

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; 
     } 
    } 

Và một DefaultProxyBuilder tùy chỉnh:

/// <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); 
     } 
    } 

Và một DefaultProxyFactory tùy chỉnh:

/// <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()); 
     } 
    } 

Và thiết lập container:

 container = new WindsorContainer(); 

     container.Kernel.ProxyFactory = new DefaultProxyFactory(); 

Tôi không thích phải thay đổi lâu đài.Các nguồn khác, vì vậy tôi thực sự muốn nghe suy nghĩ của bạn Krzysztof ... có lẽ bạn có thể làm cho những lĩnh vực đó được bảo vệ nếu giải pháp này không hoạt động cho các thử nghiệm khác các trường hợp?

+0

Hmm thú vị - vì vậy tôi cho rằng sự khác biệt quan trọng ở đây có thể là bạn ký hợp đồng được tạo ra với cùng khóa như cụm của riêng bạn, trong khi bình thường nếu DP tạo ra tên lắp ráp mạnh, nó được ký bằng khóa của Castle. Vì vậy, tôi ** đoán ** rằng có lẽ quy tắc là bạn có thể sử dụng kiểu nội bộ từ assembly A trong assebly B nếu A có B là bạn và cả hai đều được ký với cùng một khóa. –

+0

Cảm ơn bạn đã điều tra - hãy đặt điều này trong trình theo dõi vấn đề và chúng tôi sẽ xem xét việc nướng nó trong vNext. –

+0

Cảm ơn bạn đã theo dõi nhanh! – Jeff

0

Tôi có thể hoàn toàn không tham gia ở đây, nhưng bạn có đang tìm kiếm IncludeNonPublicTypes() không?

From the documentation:

Đăng ký các loại ngoài công lập

Bằng cách chỉ mặc loại có thể nhìn thấy từ bên ngoài lắp ráp sẽ được đăng ký. Nếu bạn muốn bao gồm các loại ngoài công lập, bạn phải bắt đầu với định lắp ráp đầu tiên, và sau đó gọi IncludeNonPublicTypes

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

Không, tôi đang thực hiện đăng ký của mình theo cách thủ công. Loại được đăng ký tốt, nó chỉ là trên thế hệ proxy mà nó thổi lên (vì mã được trích dẫn ở trên). – Jeff

+0

Hmmmm. Sau đó, tôi không có ý tưởng. Bạn thực sự không thể làm cho các lớp của bạn được công khai: P. –

0

Lý do cho điều đó là Silverlight mô hình bảo mật không cho phép chúng ta xây dựng một proxy cho một loại nội bộ, ngay cả với InternalsVisibleTo.

+0

Làm thế nào bạn đề nghị tiếp cận điều này từ quan điểm thiết kế? Tôi thực sự không muốn tất cả các bên trong mã của tôi tiếp xúc với người tiêu dùng ... chỉ có các giao diện ... Cảm ơn. – Jeff

+0

Lưu ý thú vị bên ... Tôi đã sao chép DefaultProxyBuilder từ .NET 4.0 vào mã của tôi, sau đó tạo vùng chứa Windsor của tôi với ProxyFactory giả tạo instantiates trường máy phát điện với ProxyGenerator đề cập đến DefaultProxyBuilder mới của tôi ... và nó hoạt động trong kiểm tra đơn vị! Nhưng tôi đoán nó sẽ không hoạt động khi tôi cố gắng thực sự chạy nó dưới thời gian chạy SL ... – Jeff

+0

vâng, nó không thành công trên Silverlight trong hộp cát bảo mật Silverlight, ít nhất nó đã làm khi tôi chạy thử nghiệm. Hãy thử nó ra, nếu bạn tìm thấy một giải pháp tôi rất vui khi nướng nó. –

Các vấn đề liên quan