首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用castle.Dynamicproxy装饰结构图4返回的所有实例

用castle.Dynamicproxy装饰结构图4返回的所有实例
EN

Stack Overflow用户
提问于 2016-09-16 13:02:17
回答 1查看 250关注 0票数 0

现在,我正在装饰我的 StructureMap4 映射类型,比如,在StructureMap4注册表中用一个带有tryCatchInterceptor的城堡生成的代理来装饰IFormsAuthenticationProvider。例如:

代码语言:javascript
复制
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定义类似的装饰器,此时代码将变得重复。

问:是否有办法在一个共同的地方,对所有类型,不重复?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-19 12:51:36

经过大量的研发之后,我不认为在structuremap4.0版本中存在这样的机制。

然而,我想出了一个我自己的动态解决方案。

创建类模板并动态创建类。编译并运行代码后将类加载到内存中。

classTemplate.txt

代码语言:javascript
复制
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中,编写了加载它的代码。

代码语言:javascript
复制
    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());
                }
            }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39532208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档