View Full Version : Spring.Aop with Advices in more than one Assembly
mruanova
05-02-2006, 05: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, 05: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, 05: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, 05:58 PM
has anybody used advices in more than one assembly?
Mark Pollack
05-02-2006, 08: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, 09: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, 10: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, 10:20 PM
app.config
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://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: Assembly:
Factory.UnitTests.dll
26595515 [7212] DEBUG Spring.Context.Support.AbstractApplicationContext (null) - Refreshing application context [XmlApplicationContext;hashCode=1726].
26595546 [7212] DEBUG Spring.Objects.Factory.Support.AbstractObjectDefin itionReader (null) - Loading XML object definitions from config [objects]
26595546 [7212] DEBUG Spring.Objects.Factory.Xml.XmlResourceReader (null) - Loading object definitions...
26595562 [7212] DEBUG Spring.Objects.Factory.Xml.XmlResourceReader (null) - Default lazy init ''.
26595562 [7212] DEBUG Spring.Objects.Factory.Xml.XmlResourceReader (null) - Default dependency check ''.
26595562 [7212] DEBUG Spring.Objects.Factory.Xml.XmlResourceReader (null) - Default autowire ''.
Error instantiating context.
TestCase 'Factory.UnitTests.FactoryBaseTest.CreateProxy_MyS ampleBO' failed: System.Configuration.ConfigurationException: Error instantiating context.
Factory\impl\factorybase.cs(154,0): at Factory.Impl.FactoryBase.CreateProxy(String objectId)
Factory\unittests\factorybasetest.cs(137,0): at Factory.UnitTests.FactoryBaseTest.CreateProxy_MySa mpleBO()
Bruno Baia
05-02-2006, 10:34 PM
I need more information, doesn't it shows the innerexception ?
-Bruno
mruanova
05-02-2006, 10:37 PM
- ex {"Error instantiating context." } System.Exception
+ [System.Configuration.ConfigurationException]
{System.Configuration.ConfigurationException} System.Configuration.ConfigurationException
+ _innerException {"Cannot instantiate Type [Spring.Context.Support.XmlApplicationContext]
using ctor [Void .ctor(Boolean, System.String[])] : 'Exception has been thrown by the target of an invocation.'" }
System.Exception
+ [Spring.Objects.FatalObjectException]
{Spring.Objects.FatalObjectException} Spring.Objects.FatalObjectException
+ _innerException {"Exception has been thrown by the target of an invocation." }
System.Exception
+ [System.Reflection.TargetInvocationException]
{System.Reflection.TargetInvocationException} System.Reflection.TargetInvocationException
+ _innerException {"Error registering object with name 'beforeAdviceDAO' defined in 'config [objects] at line 40' :
Object class [Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice] not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Integration.DAO.Advices.ConsoleLoggingBefo reAdvice\" xmlns=\"http://www.s..." }
System.Exception
+ [Spring.Objects.Factory.ObjectDefinitionStoreExcep tion]
{Spring.Objects.Factory.ObjectDefinitionStoreExcep tion} Spring.Objects.Factory.ObjectDefinitionStoreExcept ion
+ _innerException {"Could not load type from string value 'Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice'" }
System.Exception
+ [System.TypeLoadException] {""} System.TypeLoadException
_innerException { } System.Exception
mruanova
05-02-2006, 10: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(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;
}
Bruno Baia
05-02-2006, 10: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 {"Error registering object with name 'beforeAdviceDAO' defined in 'config [objects] at line 40' :
Object class [Samples.Integration.DAO.Advices.ConsoleLoggingBef oreAdvice] not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Integration.DAO.Advices.ConsoleLoggingBefo reAdvice\" xmlns=\"http://www.s..." }
-Bruno
mruanova
05-02-2006, 11:04 PM
sorry, this is the inner exception, the other was not the good one.
- ex {"Error instantiating context." }
System.Exception
+ [System.Configuration.ConfigurationException] {System.Configuration.ConfigurationException} System.Configuration.ConfigurationException
- InnerException {"Cannot instantiate Type [Spring.Context.Support.XmlApplicationContext]
using ctor [Void .ctor(Boolean, System.String[])] : 'Exception has been thrown by the target of an invocation.'" }
System.Exception
+ [Spring.Objects.FatalObjectException] {Spring.Objects.FatalObjectException}
Spring.Objects.FatalObjectException
- InnerException {"Exception has been thrown by the target of an invocation." }
System.Exception
+ [System.Reflection.TargetInvocationException] {System.Reflection.TargetInvocationException} System.Reflection.TargetInvocationException
- InnerException {"Error registering object with name 'beforeAdviceDAO' defined in 'config [objects] at line 16' :
Object class [Samples.Advices.ConsoleLoggingBeforeAdvice,Sample s.Integration.DAO] not found.
<object id=\"beforeAdviceDAO\" type=\"Samples.Advices.ConsoleLoggingBeforeAdvice,Samples .Integration.DAO\" xmlns..." }
System.Exception
+ [Spring.Objects.Factory.ObjectDefinitionStoreExcep tion] {Spring.Objects.Factory.ObjectDefinitionStoreExcep tion} 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, 11: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, 11: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://spring/objects" />
</context>
<objects xmlns="http://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, 11:58 PM
thank you so much guys
i think the types were wrong typed!
vBulletin® v3.7.3, Copyright ©2000-2009, Jelsoft Enterprises Ltd.