View Full Version : Using IOC container to proxy instances?
jjarrel
08-02-2007, 02:11 AM
From a web service I get an Array of simple domain objects (PONO). I will be moving the "rows" into a BindingList for binding to my GUI.
The advice that I want to apply today is adding a IsModified property (using AOP quick start) and also adding a ColumnChanged event.
I've done this in code with the ProxyFactory. I think it would be better to use the IOC container in case i'd want to add other advice later. I know i might still have to do the event binding after I get back the proxy from the IOC.
The rows are already instantiated so I would think that I would do something like
BindingList list = new BindingList()
for each row in incomingArraylist
{
obj = ctx.GetObject("id",row)
list.add(obj)
}
If this is possible, what would the XML look like? Is there a more appropriate approach?
Thanks,
jeff
Bruno Baia
08-02-2007, 01:40 PM
Hi,
How does this look like programmatically with the ProxyFactory ?
Bruno
jjarrel
08-02-2007, 04:41 PM
I don't have the code with me here at work and it is in just a simple test. Perhaps, it isn't doing what I think it is doing. (I will post it when I get home).
Just to confirm, it is possible to add advise (proxy\decorate) an existing object?
Thanks,
jeff
jjarrel
08-03-2007, 01:34 AM
Ok, here it is. It seems to be doing what I expect.
BaseElement is domain class with properties declared virtual.
The ModificationAdvisor and IsModifiedAdvisor are taken straight from the AOP sample, step 6.
Thanks,
jeff
[Test]
public void TestAOP()
{
ArrayList a = new ArrayList();
BaseElement baseElement;
ProxyFactory pf = new ProxyFactory();
pf.AddAdvisor(new ModificationAdvisor(typeof(BaseElement)));
pf.ProxyTargetType = true;
for (int i = 0; i < 10; i++)
{
baseElement = new BaseElement();
baseElement.ElementName = "name_" + i.ToString();
baseElement.Description = i.ToString();
pf.Target = baseElement;
pf.AddIntroduction(new IsModifiedAdvisor());
BaseElement b2 = (BaseElement)pf.GetProxy();
Debug.WriteLine("AddedAdvice");
a.Add(b2);
}
IIsModified myObj;
baseElement = (BaseElement) a[2];
myObj = (IIsModified)baseElement;
Assert.IsFalse(myObj.IsModified, "Not Modified");
baseElement.Description = "aa";
Assert.IsTrue(myObj.IsModified, "Is Modified");
baseElement = (BaseElement)a[3];
myObj = (IIsModified)baseElement;
Assert.IsFalse(myObj.IsModified, "Not Modified");
}
Bruno Baia
08-06-2007, 12:48 AM
Hi,
you can define all your domain classes into a single domain.xml file, and then configure an autoproxy to apply your introduction automatically.
<!-- Domain objects ("ends by 'Domain') -->
<object id="BaseElementDomain" type="BaseElementType" singleton="false"/>
<object id="AnotherElementDomain" type="BaseElementType" singleton="false"/>
<!-- ... -->
<object id="ModificationAdvisor" type="..."/>
<object id="IsModifiedIntroductionAdvisor"" type="..." />
<object type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxy Creator">
<property name="ProxyTargetType" value="True"/>
<property name="ObjectNames">
<list>
<value>*Domain</value>
</list>
</property>
<property name="InterceptorNames">
<list>
<value>ModificationAdvisor</value>
<value>IsModifiedIntroductionAdvisor</value>
</list>
</property>
</object>
To create a new instance of an domain class, you just need to call GetObject instead of using "new".
Btw, to use introductions with auto proxies we have to get one of the latest nightly build.
Anyway, you can still use a basic ProxyFactoryObject configuration approach.
<object type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="TargetName" value="TARGETOBJECTNAMEHERE"/>
<property name="ProxyTargetType" value="True"/>
<property name="InterceptorNames">
<list>
<value>ModificationAdvisor</value>
</list>
</property>
<property name="IntroductionNames">
<list>
<value>IsModifiedIntroductionAdvisor</value>
</list>
</property>
</object>
HTH,
Bruno
jjarrel
08-18-2007, 03:16 PM
Ok, looks good. I will give that a try.
Thanks,
jeff
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.