1

I have updated my project with the Spring.net Dependency Injection Framwork. Then I continued with integrating AOP to enable a simple logging/trace mechanism. I had some problems with a circular dependendy in my app.config, but I worked it out:

<spring>
<context>
  <resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
  <object id="loggingAroundAdvice" type="SetupBuilder.LoggingAroundAdvice"/>
  <object id="myServiceObjectTarget" type="SetupBuilder.SetupBuilderModelView, SetupBuilder">
  <!--<object name="Model" type="SetupBuilder.SetupBuilderModelView, SetupBuilder">-->
    <constructor-arg index="0" ref="MasterData"/>
    <property name="FileSelection" ref="FileSelection"/>
    <property name="Persistence" ref="Persistence"/>
    <property name="Distributor" ref="Distributor"/>
    <property name="Document" ref="Document"/>
    <property name="StatusWindow" ref="StatusWindow"/>
  </object>
  <object name="Model" type="Spring.Aop.Framework.ProxyFactoryObject">
    <property name="target" ref="myServiceObjectTarget"/>
    <property name="interceptorNames">
      <list>
        <value>loggingAroundAdvice</value>
      </list>
    </property>
  </object>
  <object name="MasterData" type="VMRedistMasterData.Implementation.VMRedistMasterDataImpl, VMRedistMasterData"/>
  <object name="FileSelection" type="SetupBuilder.OpenAndSaveDialog, SetupBuilder"/>
  <object name="Persistence" type="VMRedistDelivery.Implementation.Persistence.DeliveryPersistence, VMRedistDelivery"/>
  <object name="Distributor" type="VMRedistDelivery.Implementation.Distribution.Distributor, VMRedistDelivery"/> 
  <object name="Document" type="Word2010ReleaseDocument.Word2010ReleaseDocument, Word2010ReleaseDocument"/>
  <object name="StatusWindow" type="SetupBuilder.WpfStatusWindow, SetupBuilder">
    <constructor-arg index="0" ref="Model"/>
  </object>
</objects>

My class looks like this:

public interface ISetupBuilderModelViewDependencies
{
    IVMRedistMasterData MasterData { get; set; }
    IFileSelection FileSelection { get; set; }
    IVMRedistPersistence Persistence { get; set; }
    IVMRedistDistributor Distributor { get; set; }
    IVMRedistReleaseDocument Document { get; set; }
    IStatusWindow StatusWindow { get; set; }
}

public class SetupBuilderModelView : ISetupBuilderModelView, ISetupBuilderModelViewDependencies, INotifyPropertyChanged
{
...
    public string Customer
    {
        get { return customer; }
        set
        {
            customer = value;
            FirePropertyChanged("Customer");
        }
    }
...
}

Here is the Model object assigned to my main WPF window:

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var context = ContextRegistry.GetContext();

        var setupBuilderWindow = new SetupBuilderWindow(context.GetObject("Model") as ISetupBuilderModelView);
        // SetupBuilderWindow needs an ISetupBuilderModelView argument.                             
        setupBuilderWindow.Show();
    }
}

But if changes in the "Model" object occur, my WPF window is not updated anymore! The Property changed. The PropertyChanged event is thrown and someone has subscribed it. But noone tries to get the Property values. The trace/logging mechanism works, get_Customer() is only called once at startup, then never again. I don't get it. The Spring.Aop.Framework.ProxyFactoryObject should transfer every event from the target object to all subscribers, shouldn't it? If that's not the problem and the event arrives, is the problem in the property? Is the Proxy object caching the target's properties? I just don't get it.

The commented line in app.config was without AOP. If I comment the line above and uncomment that line, everything works normal.

If you have any idea, please let me know. I hope I provided enough but not too much information. If you need further information, i would be happy to provide it.

Marijn
  • 10,367
  • 5
  • 59
  • 80
dutop
  • 59
  • 1
  • 5
  • Moving the myServiceObjectTarget object into the Model object didn't work. Calling the factory programmatically didn't work. – dutop Mar 29 '11 at 07:30
  • The factory-created object doesn't seem to be that tough connected to the normal object as i thought. The advice _only_ reacts to changes by the WPF window. Changes inside the SetupBuilderModelView class don't appear. – dutop Mar 29 '11 at 07:39

1 Answers1

0

Your last comment reminds me of this question. In his answer, Mark Pollack (Spring developer) suggests to put this in your configuration:

<aop:config proxy-target-type="true">

This will create an inheritance based proxy. By default, Spring AOP creates a composition based proxy for your class, so any internal methods are not intercepted, because an instance has a reference to itself and not to its Spring-created proxy.

Note that events aren't automatically propagated from target to proxy. This is (probably) why the changes from your model don't propagate to your wpf window: the model fires a property change, but your window is bound to the proxy. In the question spring-aop-mvvm-foundation-propertychanged I've tried to explain this in detail and have proposed a (hackish) work-around.

Community
  • 1
  • 1
Marijn
  • 10,367
  • 5
  • 59
  • 80
  • I'm really curious if this works for you. The current documentation ([aop 13.6](http://www.springframework.net/doc-latest/reference/html/aop.html#aop-proxy-mechanism)) suggests not, but Mark's answer suggests it will work. – Marijn Mar 29 '11 at 13:44
  • Don't forget to declare any methods / properties you want to intercept as virtual. – Marijn Mar 29 '11 at 13:45
  • And you should use spring 1.3.1 or later. – Marijn Mar 29 '11 at 13:47
  • Related: http://stackoverflow.com/questions/478858/injecting-advice-to-a-recursive-method-in-spring-net – Marijn Mar 29 '11 at 14:09
  • Thank you very much, now i understand where the problem is. I've set methods and properties to virtual. I tried setting the config entry (hard enough if you don't know about the namespace and the parser). It didn't work. Then i tried using the programmatically factory call (factory.ProxyTargetType=true). It didn't work. I don't know what type an object is, i have to change my code to make everything virtual and i'm using a bloated config.app. Spring.net AOP doesn't sound that good anymore... – dutop Mar 30 '11 at 06:34
  • You might want to take a look at http://stackoverflow.com/questions/5836605/spring-aop-mvvm-foundation-propertychanged, where exactly your issue is addressed. – Marijn Jun 01 '11 at 15:12