4

我在 spring.net 论坛上发帖,但也希望我能在这里得到一些有价值的观点:

我正在寻找一些关于如何实现以下要求的建议。

首先是一些背景知识 - 我正在使用 Spring.NET 在我的 asp.net c# 多层 Web 应用程序中实现 IOC depdenecny 注入。注入是通过 spring.net xml 配置文件实现的,我的所有开发都是通过针对接口进行开发并在需要时注入接口实现的类来实现的。这一切对我来说都很好。我相信我的知识将是中级水平。

我遇到了这个问题,并希望找到解决方案。

举个例子,我有一个类有几个方法,它们都从数据库中检索,数据被缓存了一段时间。

我希望可以自由地将缓存的特性注入到每种方法中,例如。是时候让它存在于缓存等中。因此,与其将类注入到所需的位置,我还希望能够将值注入到方法中。

我可以采用为每个方法在类上创建属性的方法,但这会变得混乱,或者将设置注入我的类。我的偏好是通过弹簧注入来控制每种方法。

因此,任何想法如何实现这一点,正如我所期望的那样,比其他人可能遇到的事情。

我想出的一个可能的想法是通过spring以某种方式向每个方法注入一个属性,该属性的属性具有方法中所需的值,例如缓存持续时间等。这是一个可行的解决方案吗?如果是这样,任何人都可以帮助我进行配置。

或者,如果有人有任何其他想法,那就太好了。

4

2 回答 2

6

如果您采用 bbaia 的方法,它可能类似于下面的示例。它有点简化,但您可以将其应用于您的情况。假设我们有一个IDoWorkForSomeTime带有单个参数的接口time

public interface IDoWorkForSomeTime
{
    void Work(int time);
}

它由TimeBoundWorkerand实现AdvisedTimeBoundWorker

public class TimeBoundWorker : IDoWorkForSomeTime
{
    public void Work(int time)
    {
        Console.WriteLine("Working for {0} hours", time);
    }
}

public class AdvisedTimeBoundWorker : IDoWorkForSomeTime
{
    /* *** Note The Attribute *** */
    [ChangeParameter]
    public void Work(int time)
    {
        Console.WriteLine("Working for {0} hours", time);
    }
}

然后我们可以配置一个AOP代理在运行时改变时间参数,这样当我们运行下面的程序时:

class Program
{
    static void Main(string[] args)
    {
        IApplicationContext ctx = new XmlApplicationContext("objects.xml");
        var worker = (IDoWorkForSomeTime)ctx.GetObject("plainWorker");
        var advisedWorker = (IDoWorkForSomeTime)ctx.GetObject("advisedWorker");

        worker.Work(4);
        advisedWorker.Work(4);
    }
}

它输出:

Working for 4 hours
Working for 8 hours

因此,虽然我用值 4 调用它,但advisedWorker使用值 8,这是我在我的 spring 配置文件中配置的。spring 容器看到该[ChangeParameter]属性并从我的配置中知道它必须应用以下方法拦截器:

public class ChangeParamInterceptor : IMethodInterceptor
{
    public int NewValue { get; set; }  // set in spring cofig

    public object Invoke(IMethodInvocation invocation)
    {
        invocation.Arguments[0] = NewValue; // change the argument
        object rval = invocation.Proceed();
        return rval;
    }
}

它需要这个弹簧配置objects.xml

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">

  <object id="plainWorker"
          type="Examples.Aop.Shared.TimeBoundWorker, Examples.Aop.Shared"
          singleton="true">
  </object>

  <object id="advisedWorker"
          type="Examples.Aop.Shared.AdvisedTimeBoundWorker, Examples.Aop.Shared"
          singleton="true">
  </object>

  <!-- AOP configuration: -->

  <object id="changeParamAdvice"
          type="Examples.Aop.Shared.ChangeParamInterceptor, Examples.Aop.Shared">
    <!-- AH! there's the 8 -->
    <property name="NewValue" value="8" />
  </object>

  <object id="attributePointcut" type="Spring.Aop.Support.AttributeMatchMethodPointcut, Spring.Aop">
    <property name="Attribute" value="Examples.Aop.Shared.ChangeParameterAttribute, Examples.Aop.Shared" />
  </object>

  <object id="changeParamAspect" type="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop">
    <property name="Pointcut" ref="attributePointcut" />
    <property name="Advice" ref="changeParamAdvice"/>
  </object>

  <object id="ProxyCreator" 
          type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop" />     
</objects>

您有更多选项来配置 AOP 和应用建议,例如ChangeParamInterceptor. 阅读更多关于 AOP 的 Spring.NET 文档

于 2011-07-15T13:05:11.737 回答
0

您可以尝试使用Spring.NET AOP。您可以在运行时更改方法参数。

于 2011-07-12T13:58:00.507 回答