c# - 在简单注入(inject)器中调用拦截的方法调用上的函数

标签 c# simple-injector interception

我想要实现的是拦截类的注入(inject),并调用该类的特定方法来改变它的行为。

我已经实现了interceptor class这是在 SimpleInjector 网站上给出的,并且这是有效的,因此我能够在类被拦截时运行一些功能。

我的容器正在这样注册:

container.InterceptWith<MyInterceptor>(type => type == typeof(IMyClass));

我正在拦截的类看起来是这样的:

public class MyClass : IMyClass
{
    private IAnotherClass m_class;
    public MyClass(IAnotherClass _class)
    {
         m_class = _class;
    }

    public void MethodToCall()
    {
         //changes properties on class
    }
}

我的拦截器类如下所示:

public class MyInterceptor : IInterceptor
{
    private readonly ILogger logger;

    public MyInterceptor(ILogger logger)
    {
        this.logger = logger;
    }

    public void Intercept(IInvocation invocation)
    {
        var watch = Stopwatch.StartNew();

        // Calls the decorated instance.
        invocation.Proceed();

        var decoratedType = invocation.InvocationTarget.GetType();

        logger.Trace(string.Format("{0} executed in {1} ms.",
            decoratedType.Name, watch.ElapsedTicks));
    }
}

我想要实现的是调用拦截的 IMyClass 上的方法。所以在拦截器中,调用MyClass.MethodToCall()

我尝试在 Intercept() 方法中执行类似的操作:

var classIntercepted = invocation.ReturnValue;
MethodInfo method = invocation.InvocationTarget.GetType().GetMethod("MethodToCall");
object magicValue = method.Invoke(classIntercepted, null);

但是,inplication.ReturnValue 并未返回 MyClass 实例,而是返回 IAnotherClass 实例

最佳答案

为什么不使用装饰器而不是使用拦截呢?这通常更容易、更易于维护且更快。

这是一个例子:

public class PropSetMyClassDecorator : IMyClass
{
    private MyClass decoratee;
    public PropSetMyClassDecorator(MyClass decoratee) {
        this.decoratee = decoratee;
    }

    public void MethodToCall() {
        this.decoratee.SetConnectionString();
        this.decoratee.MethodToCall();
    }
}

您可以按如下方式注册此装饰器:

container.Register<IMyClass, PropSetMyClassDecorator>();

请注意,我们只注册装饰器,而不是注册MyClass。由于装饰器直接依赖于MyClas(而不是接口(interface)),MyClass将被Simple Injector自动解析。

另一种选择是注册初始化程序,如下所示:

container.RegisterInitializer<MyClass>(instance => {
    instance.SetConnectionString();
});

每次构造 MyClass 实例后都会调用初始化器委托(delegate)。在这种情况下,行为有点不同,因为该方法不是每次都调用,而是仅在构造期间调用。但是,通常情况下,这应该足够了,因为您通常不应在运行时更改服务,因为您会使事情变得复杂。

关于c# - 在简单注入(inject)器中调用拦截的方法调用上的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25446025/

相关文章:

c# - 处理表单时如何获取更新的 FormView 值?

simple-injector - 带有第三方 DI 的 IStringLocalizer

c# - 未注册类型的 SimpleInjector 强制 Lifestyle.Transient

c# - 容器初始化后配置unity拦截

c# - 在 Unity 中,改变 x 和 y 旋转也会奇怪地改变 z 值

c# - System.Threading.Timer 在等待时是否消耗线程?

wcf - 在Unity容器中注册WCF服务

linux - 使用 g++ 在 Linux 上使用 Valgrind 拦截全局函数

C# 避免重复代码,使用泛型

c# - 简单注入(inject)器和[导出属性]