PDA

View Full Version : Help with Spring Aop Configuration


hpcd
09-07-2006, 07:03 PM
I have a windows service. I want to instrument monitoring on the OnStart event of the service. Here is what I've done in the app.config file:

<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
...
....
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object id="serviceInfoAfterStartAdvice"
type="Spring.Aop.Support.RegularExpressionMethodPointcut Advisor">
<property name="pattern" value="OnStart"/>
<property name="advice">
<object type="Integration.Monitor.ServiceInfoAdvice"/>
</property>
</object>
<object id="Service" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="ServiceObjectTarget" type="Integration.Service.Service"/>
</property>
<property name="interceptorNames">
<list>
<value>serviceInfoAfterStartAdvice</value>
</list>
</property>
</object>
</objects>
</spring>

ServiceInfoAdvise is as follows:

public class ServiceInfoAdvise: IAfterReturningAdvice
{

public ServiceInfoAdvise() {}

#region IAfterReturningAdvice Members

public void AfterReturning(object returnValue, System.Reflection.MethodInfo method, object[] args, object target)
{
string svcIdentity = (string)args[0];

// Do some database access to to update monitoring statistics

}

#endregion
}
I don't see anything happening. No errors, nothing. Any suggestions? Thanks.
PS. How do you pass in arguments here? Are these arguments passed to the method?

Bruno Baia
09-08-2006, 10:12 AM
Hi,

How looks your Integration.Service.Service class ? (interface, OnStart method signatures, etc...)
Are you using the official realease 1.0.2 or the latest nighlty build ?


-Bruno

hpcd
09-08-2006, 03:56 PM
Hi Bruno:

I'm using the offician 1.02 release. Also, it is regular Windows service class which inherits from ServiceBase. I'm not using the spring service. Does the app.config looks correct?

Bruno Baia
09-11-2006, 01:28 PM
Hi,

The OnStart method is protected, so you can't apply an advice on it.
This will be supported with inheritance proxy planned for the 1.2 version.

-Bruno

hpcd
09-11-2006, 04:29 PM
Thanks. If I raise an event internally to the service (publicly declared handler), and I set the advise on this handler, it should work then? right?

Bruno Baia
09-12-2006, 02:27 PM
Yeah, you can do somethign like that.

exemple :

private IMyService _service;
public IMyService Service
{
set { _service = value; }
}

protected override void OnStart(string[] args)
{
_service.Start(args);
}


You can apply aspects to the IMyService implementation and then inject it to the windows service class.
This is also a nice way to decouple the service from the windows service.


Hope this helps,
Bruno

hpcd
09-13-2006, 04:23 PM
Hi Bruno, thanks for the suggestions. I've wrapped my service implementation into another class with public methods:

public class ServiceMaster
{
...
public ServiceMaster(..) { .... }

public bool StartService(string[] args) {}
public bool StopService() {}
...
...
}

I've defined my configuration as follows:

<!-- Service Monitoring -->
<object id="serviceInfoAdvice"
type="Spring.Aop.Support.RegularExpressionMethodPointcut Advisor">
<property name="pattern" value="*StopService*"/>
<property name="advice">
<object type="Integration.Monitor.ServiceInfoAdvise"/>
</property>
</object>
<object id="ServiceObject"
type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="ServiceObjectTarget"
type="Integration.Service.ServiceMaster"/>
</property>
<property name="interceptorNames">
<list>
<value>serviceInfoAdvice</value>
</list>
</property>
</object>

It still doesn't seem to work.
My advise class (Integration.Monitor.ServiceInfoAdvise):

public void AfterReturning(object returnValue, System.Reflection.MethodInfo method, object[] args, object target)
{
TraceFactory.Instance.Trace.TraceEvent(System.Diag nostics.TraceEventType.Verbose, 1, "AfterReturning Advise execution!!");

}

I don't see the entry in the eventlog and there aren't any errors. I think it must be something simple I'm missing.

Bruno Baia
09-13-2006, 05:21 PM
Hi,

In 1.0.2, you only can proxy objects that implement an interface.
So you need to create an IServiceMaster interface here :

public interface IServiceMaster
{
bool StartService(string[] args);
bool StopService();
}




Btw, if you get the latest nightly build (http://www.springframework.net/downloads/nightly/), you can proxy non interface implemented objects, but the methods needs to be virtual.

public class ServiceMaster
{
...
public ServiceMaster(..) { .... }

public virtual bool StartService(string[] args) {}
public virtual bool StopService() {}
...
}



Cheers,
Bruno

hpcd
09-13-2006, 05:57 PM
Hi Bruno, thanks for such prompt reply!! I just added:


public interface IServiceMaster
{
bool StartService(string[] args);
bool StopService();
void ExecuteCustomCommand(int command);
}


and changed my class to:

public class ServiceMaster: IServiceMaster
{
...
public bool StartService(string []args) { ... }
public bool StopService() { ... }
void ExecuteCustomCommand(int command) { ... }
...
...
etc
}
I left my app.config as :

<object id="serviceInfoAdvice"
type="Spring.Aop.Support.RegularExpressionMethodPointcut Advisor">
<property name="pattern" value="*StopService*"/>
<property name="advice">
<object type="Integration.Monitor.ServiceInfoAdvise"/>
</property>
</object>
<object id="ServiceObject"
type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="ServiceObjectTarget"
type="Integration.Service.ServiceMaster"/>
</property>
<property name="interceptorNames">
<list>
<value>serviceInfoAdvice</value>
</list>
</property>
</object>

Do I need to make any changes in this config?
Anyways, as above, I executed it and still no response- don't see the advise executing.

Bruno Baia
09-13-2006, 07:59 PM
Hi,

I've added an example (http://opensource.atlassian.com/confluence/spring/download/attachments/708/SimpleWindowsService.zip?version=1) to the forum question page (http://opensource.atlassian.com/confluence/spring/display/NET/Forum+Questions) to demonstrate usage of Spring.Aop with ServiceBase methods.

Hope this helps,
Bruno

hpcd
09-13-2006, 11:57 PM
Bruno, thanks a million for the sample!! You'll never believe that all along the problem was in program.cs:-

I was missing:


IApplicationContext ctx = ContextRegistry.GetContext();
WinHostService winService = ctx.GetObject("winService") as WinHostService;


Intially, even with your code, I copied and pasted your classes, interfaces and nothing. I just now decided to peek at your program.cs: I now feel like beating-up myself and celebrating at the same time :mrgreen:

Thanks again, for taking the time to write a sample and looking into my problems.