Spring for .NET Community Forums    

Go Back   Spring for .NET Community Forums > General > Architecture, Design and Best Practices

Reply
 
Thread Tools Display Modes
  #1  
Old 01-13-2006, 08:41 PM
sbellware sbellware is offline
Junior Member
 
Join Date: Jan 2006
Posts: 5
Default Programatic Add of an Object to a Context?

Hi all,

Is there a way to instantiate a context, and then add a pre-existing instance of an object to it along with an ID so that it can be returned from the context by CreateObject()?

-Scott
Reply With Quote
  #2  
Old 01-14-2006, 06:11 AM
Aleks Seovic Aleks Seovic is offline
Spring.NET Co-Lead
Spring TeamSpring User
 
Join Date: Sep 2004
Location: Belgrade, Serbia
Posts: 613
Default

Of course, it's relatively easy -- all you need to do is cast your context instance to IConfigurableApplicationContext, which will give you access to the underlying object factory that you need to register object with:

Code:
((IConfigurableApplicationContext) applicationContext).ObjectFactory.RegisterSingleton("MyObjectId", myObject);
Keep in mind that this will work, as the method name says, only for singletons. If you need to add a prototype programatically it is possible but a bit more involved, as you need to create the whole object definition for it and add definition to object factory.

HTH,

Aleks
Reply With Quote
  #3  
Old 01-15-2006, 06:07 AM
sbellware sbellware is offline
Junior Member
 
Join Date: Jan 2006
Posts: 5
Default

Hi Aleks. Thanks for the response.

I think I could probably get away with using the singleton, but I'd be interested in investigating what's involved in doing this for a prototype. If you could point me in the direction of the topics that I need to take a look at, it'd be much apppreciated.

-Scott
Reply With Quote
  #4  
Old 01-16-2006, 02:38 AM
Aleks Seovic Aleks Seovic is offline
Spring.NET Co-Lead
Spring TeamSpring User
 
Join Date: Sep 2004
Location: Belgrade, Serbia
Posts: 613
Default

Hi Scott,

I'm not sure this topic is much documented, mostly because it's fairly advanced usage scenario that shouldn't be necessary for most applications. Our recommendation is to simply configure all the objects you need within the context and use programmatic registration only for special cases.

That said, I'll try to describe the steps necessary to create object definitions programatically and register them with the application context. This approach will allow you to create definitions for both singletons and prototypes, but as I mentioned in the previous post, the easiest way to register existing singleton instance is to use RegisterSingleton method instead.

There are several steps that are required to create and register object definition:

1. Create an instance of IObjectDefinitionFactory. Typically you will create an instance of DefaultObjectDefinitionFactory, but if you are writing web application you should use WebObjectDefinitionFactory instead, which adds support for Scope property and ASP.NET pages.

2. Create instances of ConstructorArgumentValues and/or MutablePropertyValues, depending on whether you want to use constructor or property injection, and add desired properties and constructor arguments to them.

3. Call IObjectDefinitionFactory.CreateObjectDefinition method, passing type name, parent object's id (if any), constructor arguments, property values and app domain that should be used to resolve types as arguments.

4. Set additional properties on the created IObjectDefinition instance, such as IsSinleton, IsLazyInit, etc.

5. Obtain a reference to IObjectDefinitionRegistry by casting application context's object factory and register object definition with it.

Here is the sample code that demonstrates the steps described above:

Code:
IObjectDefinitionFactory factory = new DefaultObjectDefinitionFactory();

ConstructorArgumentValues constructorArgs = new ConstructorArgumentValues();
constructorArgs.AddNamedArgumentValue("arg1", "MyStringValue");
constructorArgs.AddNamedArgumentValue("arg2", myObjectValue);

MutablePropertyValues properties = new MutablePropertyValues();
properties.Add("myStringProperty", "MySecondStringValue");
properties.Add("myArrayProperty", new object[] {...});
properties.Add("myReferenceProperty", new RuntimeObjectReference("objectId"));

IObjectDefinition objDef = factory.CreateObjectDefinition("MyCompany.MyObjectType, MyAssembly", null, constructorArgs, properties, AppDomain.CurrentDomain);

objDef.IsSingleton = true;    // set this to false for prototype definition
objDef.IsLazyInit = true;

IObjectFactory objectFactory = ((IConfigurableApplicationContext) applicationContext).ObjectFactory;
((IObjectDefinitionRegistry) objectFactory).RegisterObjectDefinition("myObjectId", objDef);
I guess that should be enough to get you started. Keep in mind that both property and constructor args accept many things in addition to specific object values. For example, I used RuntimeObjectReference in one of the examples, but there are also things such as ManagedList, ManagedMap, etc., that can contain nested object definitions in addition to regular objects.

If you want to see more realistic sample code, take a look at one of the configuration parsers to see how they work. Standard parser is fairly complex and intimidating, so my advice is to start with one of the simpler custom parsers, such as ValidationConfigParser, for example.

Regards,

Aleks
Reply With Quote
  #5  
Old 01-16-2006, 05:50 AM
sbellware sbellware is offline
Junior Member
 
Join Date: Jan 2006
Posts: 5
Default

Thanks, Aleks! Much appreciated!

-Scott
Reply With Quote
  #6  
Old 06-12-2006, 09:38 AM
De Fille De Fille is offline
Junior Member
New User
 
Join Date: Jun 2006
Posts: 5
Default

Hi folks,

I'm a newbie and i'm trying to add programmatic an object.
I get no errors but the object doesn't get added to my file.

What i'm a doing wrong?

my app.config
Code:
<configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
     </sectionGroup>
  </configSections>
  <spring>
    <context>
      <resource uri="file://spring.xml"/>
    </context>
  </spring>
my spring.xml
Code:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <object id="test" type="Springtest.Testclass, Springtest">
    <constructor-arg name="ID" value="2"/>
  </object>
</objects>
my code
Code:
Public Sub Register(ByVal typeID As Guid, ByVal o As Object)
        Dim factory As IObjectDefinitionFactory = New DefaultObjectDefinitionFactory
        Dim constructorArgs As New Spring.Objects.Factory.Config.ConstructorArgumentValues
        constructorArgs.AddNamedArgumentValue("ID", typeID)
        Dim objDef As Config.IObjectDefinition = factory.CreateObjectDefinition(o.GetType().ToString & "," & o.GetType().Assembly.ToString, Nothing, constructorArgs, Nothing, AppDomain.CurrentDomain)
        Dim context As IApplicationContext = ContextRegistry.GetContext()
        Dim objFactory As IObjectFactory = CType(context, IConfigurableApplicationContext).ObjectFactory
        CType(objFactory, IObjectDefinitionRegistry).RegisterObjectDefinition(o.GetType().ToString, objDef)
    End Sub
If you could help me solve this plz.

Filip
Reply With Quote
  #7  
Old 06-13-2006, 08:51 AM
Bruno Baia Bruno Baia is offline
Senior Member
Spring TeamSpring User
 
Join Date: Oct 2005
Location: Toulouse, France
Posts: 1,335
Default

Hi,

You can use IConfigurableApplicationContext.RegisterSingleton to register a singleton under a given name :

Code:
IApplicationContext ctx = ContextRegistry.GetContext();

((IConfigurableApplicationContext)ctx).ObjectFactory.RegisterSingleton("myTestObject", new TestObject());
If it's not enought for what you want to do, you can to do something more complex as shown in this topic.
Your code seems oki, have you tried to see if the object has been registered using GetObjectDefinitionNames method ?
Code:
IApplicationContext ctx = ContextRegistry.GetContext();
ctx.GetObjectDefinitionNames();
-Bruno
__________________
My english is as poor as my taylor is rich
Reply With Quote
  #8  
Old 06-13-2006, 09:20 AM
De Fille De Fille is offline
Junior Member
New User
 
Join Date: Jun 2006
Posts: 5
Default

Hi,

It seems it actually gets added to the context. But it doesn't get saved in my "spring.xml" document. I'm a missing something in my app.config or do i need to restart or save something..?

Filip
Reply With Quote
  #9  
Old 06-13-2006, 06:17 PM
natl natl is offline
Member
Spring User
 
Join Date: Aug 2005
Posts: 30
Default

De Fille,

It won't get saved into xml. The code shown by Bruno is just a way you can register a singleton object programmatically.
Reply With Quote
  #10  
Old 06-13-2006, 06:44 PM
De Fille De Fille is offline
Junior Member
New User
 
Join Date: Jun 2006
Posts: 5
Default

Hi,

So there isn't a way to save it into your xml file, except creating your own xmlnodes for you xmldocument and then save it?

Filip
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Object Definition Creator Bug htapal Web 0 05-07-2006 08:48 PM
Possibility to delete DataBindings sir-archimedes Web 7 05-06-2006 07:33 AM
Object does not match target type zblock Web 5 03-23-2006 01:31 PM
Storing the web application context Anonymous Web 9 07-13-2005 02:42 PM
Child object definitions and abstract classes. Tom Whitner Core Container 5 12-08-2004 07:33 PM


All times are GMT. The time now is 04:00 AM.


Contegix provides first-class managed hosting and partial sponsorship of these forums.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.