2016-09-16 31 views
0

現在,我正在裝飾我的StructureMap4映射的類型,例如IFormsAuthenticationProvider與CastleMap生成的代理在StructureMap4註冊表中具有tryCatchInterceptor。例如:使用castle裝飾結構圖4返回的所有實例。動態代理

public class AuthenticationRegistry : Registry 
{ 
    public AuthenticationRegistry() 
    { 
     var proxyGenerator = new ProxyGenerator(); 
     var tryCatchInterceptor = new TryCatchInterceptor(); 

     For<IFormsAuthenticationProvider>().Use<FormsAuthenticationProvider>() 
      .DecorateWith(x => proxyGenerator.CreateInterfaceProxyWithTarget<IFormsAuthenticationProvider>(x, tryCatchInterceptor)); 
    } 
} 

public class TryCatchInterceptor : IInterceptor 
{..} 

但正如你所看到的,我必須指定裝飾方法中的類型。因此,必須爲所有IType-> Type定義類似的裝飾器,此時代碼將變得重複。

問題:有沒有辦法在一個共同的地方做到這一點,對於所有類型沒有重複?

回答

0

之後很多R & D,我不認爲有一個現有的機制在structuremap4.0版本中做到這一點。然而,我想出了一個我自己的動態解決方案。

創建了一個班級模板,並即時創建了班級。編譯並運行代碼後,將該類加載到內存中。

classTemplate.txt

using Castle.DynamicProxy; 
using StructureMap; 
using System.Web; 
using Company1.WebApplication.App1.Meta; 
using Company1.WebApplication.App1.Meta.Interceptors; 

namespace Company1.WebApplication.App1 
{ 
    public class DynamicUtils 
    { 
     private static StructureMapDependencyResolver _structureMapResolver { get; set; } 
     private static ProxyGenerator _ProxyGenerator = new ProxyGenerator(); 

     public static void ConfigureCastleInterceptor(Container container) 
     { 
      container.Configure(x => 
       { 
        ##INTERFACE## 
       }); 
     } 
    } 
} 

,並在我的的Global.asax,寫代碼,加載它

private static void ConfigureCastleInterceptor(Container container) 
      { 
       string classBody = File.ReadAllText(HttpRuntime.AppDomainAppPath + "/RuntimeClasses/RegisterInterceptors.txt"); 
       var classBuilder = new StringBuilder(); 
       string interfaceTemplate = "x.For<##INTERFACE##>() 
.DecorateAllWith(y => _ProxyGenerator 
.CreateInterfaceProxyWithTarget<##INTERFACE##>(y, new TryCatchLoggingInterceptor())); \n"; 

       foreach (var instance in container.Model.AllInstances) 
       { 
        if (instance.PluginType.FullName.Contains("Company1.WebApplication")) 
         classBuilder.Append(interfaceTemplate.Replace("##INTERFACE##", instance.PluginType.FullName)); 
       } 
       classBody = classBody.Replace("##INTERFACE##", classBuilder.ToString()); 


       var csharp = new CSharpCodeProvider(); 
       var compiler = new CompilerParameters(); 
       foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) 
       { 
        compiler.ReferencedAssemblies.Add(asm.Location); 
       } 
       compiler.GenerateInMemory = true; 
       compiler.GenerateExecutable = false; 

       CompilerResults results = csharp.CompileAssemblyFromSource(compiler, classBody); 

       if (!results.Errors.HasErrors) 
       { 
        Assembly assembly = results.CompiledAssembly; 
        Type program = assembly.GetType("Company1.WebApplication.App1.DynamicUtils"); 
        MethodInfo configureCastleInterceptor = program.GetMethod("ConfigureCastleInterceptor"); 

        configureCastleInterceptor.Invoke(null, new Object[] { container }); 
       } 

       else 
       { 
        throw new Exception(results.Errors.ToString()); 
       } 
      } 
相關問題