PDA

View Full Version : Spring.Aop with Advices in more than one Assembly



mruanova
05-02-2006, 04:57 PM
Hola!

I have a project with two assemblies: Business and DAO, and I want to have a BeforeAdvice in each assembly. Unfortunately Spring.Aop only works with advices in one single assembly, it doesn't works with two or more assemblies.

In my configuration it works OK when I put only the beforeAdviceDAO or the beforeAdviceBO, but it doesn't work when I put both.

This is my configuration
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">

<object id="beforeAdviceDAO" type="Samples.Integration.DAO.Advices.ConsoleLoggi ngBeforeAdvice" />
<object id="mySampleDAO" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySampleDAOTarget" type="Samples.Integration.DAO.DALC.SampleDAO" />
</property>
<property name="interceptorNames">
<list>
<value>beforeAdviceDAO</value>
</list>
</property>
</object>

<object id="beforeAdviceBO" type="Samples.BusinessCore.Advices.ConsoleLoggingB eforeAdvice" />
<object id="mySampleBO" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySampleBOTarget" type="Samples.BusinessCore.BusinessObjects.Impl.Sa mpleBO" />
</property>
<property name="interceptorNames">
<list>
<value>afterAdviceBO</value>
</list>
</property>
</object>
</objects>
</spring>

mruanova
05-02-2006, 04:57 PM
Error instantiating context.
System.Configuration.ConfigurationException

Could not load type from string value 'Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice'
System.TypeLoadException

mruanova
05-02-2006, 04:58 PM
Spring.Util.TypeResolver.Resolve(string typeName)
...
// bare type name... loop thru all loaded assemblies
Assembly[] asses = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly ass in asses)
{
type = ass.GetType(typeInfo.TypeName, false, false);
if (type != null)
break;
}

In this foreach the assembly Samples.Integration.DAO cannot be found.

mruanova
05-02-2006, 04:58 PM
has anybody used advices in more than one assembly?

Mark Pollack
05-02-2006, 07:58 PM
Hi,
I will try this out explicitly and post back but it looks to me that you need to add the assembly name to the type attribute, that is instead of



<object id="beforeAdviceDAO" type="Samples.Integration.DAO.Advices.ConsoleLoggingBefo reAdvice" />


use



<object id="beforeAdviceDAO" type="Samples.Integration.DAO.Advices.ConsoleLoggingBefo reAdvice, MyDaoAssemblyName" />


Cheers,
Mark

mruanova
05-02-2006, 08:53 PM
Thank you Mark Pollack, but it gives the same result.

It works separately, but when I put both Business and DAO on the App.Config I get "Error instantiating context." :?

Bruno Baia
05-02-2006, 09:10 PM
Hi,

I don't see the definition of the interceptor name 'afterAdviceBO'.

Anyway, if you still have an error, post the exception message (like you did in your second post).

-Bruno

mruanova
05-02-2006, 09:20 PM
app.config


<spring>
<context>
<resource uri="config&#58;//spring/objects" />
</context>
<objects xmlns="http&#58;//www.springframework.net">

<object id="beforeAdviceDAO" type="Samples.Advices.ConsoleLoggingBeforeAdvice,Samples .Integration.DAO" />
<object id="mySampleDAO" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySampleDAOTarget" type="Samples.Integration.DAO.DALC.SampleDAO" />
</property>
<property name="interceptorNames">
<list>
<value>beforeAdviceDAO</value>
</list>
</property>
</object>

<object id="beforeAdviceBO" type="Samples.BusinessCore.Advices.ConsoleLoggingBeforeA dvice,Samples.BusinessCore" />
<object id="afterAdviceBO" type="Samples.BusinessCore.Advices.ConsoleLoggingAfterAd vice,Samples.BusinessCore" />
<object id="aroundAdviceBO" type="Samples.BusinessCore.Advices.ConsoleLoggingAroundA dvice,Samples.BusinessCore" />
<object id="throwsAdviceBO" type="Samples.BusinessCore.Advices.ConsoleLoggingThrowsA dvice,Samples.BusinessCore" />
<object id="mySampleBO" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySampleBOTarget" type="Samples.BusinessCore.BusinessObjects.Impl.SampleBO ,Samples.BusinessCore" />
</property>
<property name="interceptorNames">
<list>
<value>beforeAdviceBO</value>
</list>
</property>
</object>
</objects>
</spring>


exception


------ Test started&#58; Assembly&#58;
Factory.UnitTests.dll

26595515 &#91;7212&#93; DEBUG Spring.Context.Support.AbstractApplicationContext &#40;null&#41; - Refreshing application context &#91;XmlApplicationContext;hashCode=1726&#93;.
26595546 &#91;7212&#93; DEBUG Spring.Objects.Factory.Support.AbstractObjectDefin itionReader &#40;null&#41; - Loading XML object definitions from config &#91;objects&#93;
26595546 &#91;7212&#93; DEBUG Spring.Objects.Factory.Xml.XmlResourceReader &#40;null&#41; - Loading object definitions...
26595562 &#91;7212&#93; DEBUG Spring.Objects.Factory.Xml.XmlResourceReader &#40;null&#41; - Default lazy init ''.
26595562 &#91;7212&#93; DEBUG Spring.Objects.Factory.Xml.XmlResourceReader &#40;null&#41; - Default dependency check ''.
26595562 &#91;7212&#93; DEBUG Spring.Objects.Factory.Xml.XmlResourceReader &#40;null&#41; - Default autowire ''.

Error instantiating context.

TestCase 'Factory.UnitTests.FactoryBaseTest.CreateProxy_MyS ampleBO' failed&#58; System.Configuration.ConfigurationException&#58; Error instantiating context.
Factory\impl\factorybase.cs&#40;154,0&#41;&#58; at Factory.Impl.FactoryBase.CreateProxy&#40;String objectId&#41;
Factory\unittests\factorybasetest.cs&#40;137,0&#41;&#58; at Factory.UnitTests.FactoryBaseTest.CreateProxy_MySa mpleBO&#40;&#41;

Bruno Baia
05-02-2006, 09:34 PM
I need more information, doesn't it shows the innerexception ?

-Bruno

mruanova
05-02-2006, 09:37 PM
- ex &#123;"Error instantiating context." &#125; System.Exception

+ &#91;System.Configuration.ConfigurationException&#93;
&#123;System.Configuration.ConfigurationException&#125; System.Configuration.ConfigurationException

+ _innerException &#123;"Cannot instantiate Type &#91;Spring.Context.Support.XmlApplicationContext&#93;
using ctor &#91;Void .ctor&#40;Boolean, System.String&#91;&#93;&#41;&#93; &#58; 'Exception has been thrown by the target of an invocation.'" &#125;
System.Exception

+ &#91;Spring.Objects.FatalObjectException&#93;
&#123;Spring.Objects.FatalObjectException&#125; Spring.Objects.FatalObjectException

+ _innerException &#123;"Exception has been thrown by the target of an invocation." &#125;
System.Exception

+ &#91;System.Reflection.TargetInvocationException&#93;
&#123;System.Reflection.TargetInvocationException&#125; System.Reflection.TargetInvocationException

+ _innerException &#123;"Error registering object with name 'beforeAdviceDAO' defined in 'config &#91;objects&#93; at line 40' &#58;
Object class &#91;Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice&#93; not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Integration.DAO.Advices.ConsoleLoggingBefo reAdvice\" xmlns=\"http&#58;//www.s..." &#125;
System.Exception

+ &#91;Spring.Objects.Factory.ObjectDefinitionStoreExcep tion&#93;
&#123;Spring.Objects.Factory.ObjectDefinitionStoreExcep tion&#125; Spring.Objects.Factory.ObjectDefinitionStoreExcept ion
+ _innerException &#123;"Could not load type from string value 'Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice'" &#125;
System.Exception

+ &#91;System.TypeLoadException&#93; &#123;""&#125; System.TypeLoadException
_innerException &#123; &#125; System.Exception

mruanova
05-02-2006, 09:38 PM
i'm debugging and I get to this point where spring.aop gets the assemblys and is able to find only one or the another but never both (Business and DAO).


Spring.Util.TypeResolver.Resolve&#40;string typeName&#41;
...
// bare type name... loop thru all loaded assemblies
Assembly&#91;&#93; asses = AppDomain.CurrentDomain.GetAssemblies&#40;&#41;;
foreach &#40;Assembly ass in asses&#41;
&#123;
type = ass.GetType&#40;typeInfo.TypeName, false, false&#41;;
if &#40;type != null&#41;
break;
&#125;

Bruno Baia
05-02-2006, 09:54 PM
Could not load type from string value 'Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice'



There is different ways to define a type :
- using an alias
http://www.springframework.net/doc/reference/html/objects.html#context-configuration

- using the full type name, spring will try to load the type from one of the current loaded assemblies :


type="System.Collections.ArrayList"


- using the full type name with a fully/partially qualified assembly name


type="Samples.Advices.ConsoleLoggingBeforeAdvice,Samples .Integration.DAO"



Something weird is the configuration from the innerexception is different than the one you posted :


+ _innerException &#123;"Error registering object with name 'beforeAdviceDAO' defined in 'config &#91;objects&#93; at line 40' &#58;
Object class &#91;Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice&#93; not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Integration.DAO.Advices.ConsoleLoggingBefo reAdvice\" xmlns=\"http&#58;//www.s..." &#125;



-Bruno

mruanova
05-02-2006, 10:04 PM
sorry, this is the inner exception, the other was not the good one.


- ex &#123;"Error instantiating context." &#125;
System.Exception
+ &#91;System.Configuration.ConfigurationException&#93; &#123;System.Configuration.ConfigurationException&#125; System.Configuration.ConfigurationException

- InnerException &#123;"Cannot instantiate Type &#91;Spring.Context.Support.XmlApplicationContext&#93;
using ctor &#91;Void .ctor&#40;Boolean, System.String&#91;&#93;&#41;&#93; &#58; 'Exception has been thrown by the target of an invocation.'" &#125;
System.Exception
+ &#91;Spring.Objects.FatalObjectException&#93; &#123;Spring.Objects.FatalObjectException&#125;
Spring.Objects.FatalObjectException

- InnerException &#123;"Exception has been thrown by the target of an invocation." &#125;
System.Exception
+ &#91;System.Reflection.TargetInvocationException&#93; &#123;System.Reflection.TargetInvocationException&#125; System.Reflection.TargetInvocationException

- InnerException &#123;"Error registering object with name 'beforeAdviceDAO' defined in 'config &#91;objects&#93; at line 16' &#58;
Object class &#91;Samples.Advices.ConsoleLoggingBeforeAdvice,Sample s.Integration.DAO&#93; not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Advices.ConsoleLoggingBeforeAdvice,Samples .Integration.DAO\" xmlns..." &#125;
System.Exception
+ &#91;Spring.Objects.Factory.ObjectDefinitionStoreExcep tion&#93; &#123;Spring.Objects.Factory.ObjectDefinitionStoreExcep tion&#125; Spring.Objects.Factory.ObjectDefinitionStoreExcept ion


my type are defined with their Assembly, but it makes no difference:
<object id="mySampleBOTarget" type="Samples.BusinessCore.BusinessObjects.Impl.SampleBO ,IIDEA.Samples.BusinessCore" />

Bruno Baia
05-02-2006, 10:14 PM
- InnerException {"Error registering object with name 'beforeAdviceDAO' defined in 'config [objects] at line 16' :
Object class [Samples.Advices.ConsoleLoggingBeforeAdvice,Samples .Integration.DAO] not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Advices.ConsoleLoggingBeforeAdvice,Samples .Integration.DAO\" xmlns..." }


first, you should put your advices in another class library project,
then, you should have a 'Sample.Integration.DAO.dll' assembly in your bin directory to work.

-Bruno

Mark Pollack
05-02-2006, 10:36 PM
Hi,

Wow, lots of attention on this. Are you sure that you are referencing the project correctly in the main application? I have recreated your scenario and it works, advice in two different assemblies. I can't imagine why it would not have worked.

I have posted the solution on the Spring.NET wiki - you can download it here (http://opensource.atlassian.com/confluence/spring/display/NET/Forum+Questions)

There must be something simple that is being missed in the configuration, like a missing reference or typo perhaps?

Hope this helps.

Cheers,
Mark

Just to have a little sneak-peak - here is the configuration file



<?xml version="1.0" encoding="utf-8" ?>
<configuration>


<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>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

</configSections>

<spring>
<context>
<resource uri="config&#58;//spring/objects" />
</context>

<objects xmlns="http&#58;//www.springframework.net">
<description>An example that demonstrates simple AOP functionality.</description>


<object id="beforeAdviceDAO" type="DAO.Advice.ConsoleLoggingBeforeAdvice, DAO" />

<object id="myPersonDAO" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySampleDAOTarget" type="DAO.PersonDao, DAO" />
</property>
<property name="interceptorNames">
<list>
<value>beforeAdviceDAO</value>
</list>
</property>
</object>

<object id="beforeAdviceBO" type="BusinessObjects.Advice.ConsoleLoggingBeforeAdvice, BusinessObjects" />

<object id="myPerson" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="mySampleBOTarget" type="BusinessObjects.Person, BusinessObjects" />
</property>
<property name="interceptorNames">
<list>
<value>beforeAdviceBO</value>
</list>
</property>
</object>

</objects>
</spring>

<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %logger - %message%newline" />
</layout>
</appender>


<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</root>

<!-- Set logging for Spring to INFO. Logger names in Spring
correspond to the namespace -->
<!-- Note in this example, the example code uses the logging name
Spring.Examples.MovieFinder.MovieApp -->
<logger name="Spring">
<level value="INFO" />
</logger>

</log4net>

</configuration>

mruanova
05-02-2006, 10:58 PM
thank you so much guys

i think the types were wrong typed!