我怎样才能将spring.net注入方法?

ama*_*eur 4 c# asp.net dep spring.net inversion-of-control

我在spring.net论坛上发布了以下内容,但也希望我可以在这里获得一些有价值的观点:

我正在寻找一些关于如何达到以下要求的建议.

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

我已经遇到了问题并希望为它找到解决方案.

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

我希望能够自由地为每个方法注入缓存的特征,例如.时间让它存在于缓存等中.因此,我希望能够将值注入到方法中,而不是在类中注入其所需的位置.

我可以继续为每个方法在类上创建属性的方法,但这会变得混乱,或者在我的类中注入设置.我倾向于通过弹簧注射控制每种方法.

所以任何想法如何实现这一点,因为我期望它比其他人可能遇到过.

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

或者,如果任何人有任何其他想法,那将是伟大的.

Mar*_*ijn 6

如果你采用bbaia的方法,它可能看起来像下面的例子.它有点简化,但你可以将它应用到你的情况.假设我们有一个IDoWorkForSomeTime带有单个参数的接口time:

public interface IDoWorkForSomeTime
{
    void Work(int time);
}
Run Code Online (Sandbox Code Playgroud)

它是由执行TimeBoundWorkerAdvisedTimeBoundWorker:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以配置一个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);
    }
}
Run Code Online (Sandbox Code Playgroud)

它输出:

Working for 4 hours
Working for 8 hours
Run Code Online (Sandbox Code Playgroud)

所以虽然我用值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;
    }
}
Run Code Online (Sandbox Code Playgroud)

它需要这种弹簧配置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>
Run Code Online (Sandbox Code Playgroud)

您还有更多选项可用于配置AOP和应用建议,例如ChangeParamInterceptor.阅读AOP上Spring.NET文档中的更多内容.