2009-09-03 5 views
1

J'ai un objet suivant:Spring RegisterSingleton

public class TestObject 
{ 
    public String Something { get; set; } 
} 

et un objets fichier suivant:

<?xml version="1.0" encoding="utf-8" ?> 
<objects xmlns="http://www.springframework.net" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"> 

    <object id="TestObject" type="SpringTest.TestObject" autowire="byName"/> 
</objects> 

Ce que je voudrais faire est de vous inscrire et obtenir le singleton TestObject. Je fais ceci comme ceci:

IConfigurableApplicationContext context = new XmlApplicationContext("objects.xml"); 
context.ObjectFactory.RegisterSingleton("Something", "something to test"); 
object obj = context.GetObject("TestObject"); 

Mais la propriété d'objets Quelque chose est toujours nulle. Je pense que cela devrait fonctionner ou est-ce que je fais quelque chose de mal?

Merci beaucoup!

Répondre

0

Je pense que votre propriété Something n'est pas définie car les singletons sont instanciés lorsque le contexte de l'application est instancié. Lorsque vous appelez RegisterSingleton, le TestObject a déjà été créé. Le câblage du haricot n'est effectué que lorsqu'un haricot est créé.

Vous pouvez peut-être contourner ce problème en faisant instamment l'instanciation singleton paresseusement. De cette façon, il n'est pas instancié jusqu'à la première fois qu'il est demandé. J'espère que c'est après que vous avez enregistré les autres singletons dont il a besoin. Je ne sais pas exactement ce que vous essayez d'accomplir, mais si je voulais changer le câblage entre certains beans singleton au moment de l'exécution sans en avertir les beans, j'introduirais des objets wrapper. Chaque wrapper implémenterait une interface, puis déléguerait toutes les méthodes à son bean cible actuel. Pour changer le câblage, il vous suffit de changer la cible de l'encapsuleur.

Mise à jour: comme yawn suggested, Spring.NET a hot-swappable target sources que vous laissez échanger sur la mise en œuvre d'un haricot au moment de l'exécution. Voici quelques exemples de code à partir de la documentation qui montre comment échanger la mise en œuvre du haricot:

HotSwappableTargetSource swapper = 
    (HotSwappableTargetSource) objectFactory.GetObject("swapper"); 
object oldTarget = swapper.swap(newTarget); 

Les définitions XML dans le regard de la documentation comme ceci:

<object id="initialTarget" type="MyCompany.OldTarget, MyCompany"> 
</object> 

<object id="swapper" 
    type="Spring.Aop.Target.HotSwappableTargetSource, Spring.Aop"> 
    <constructor-arg><ref local="initialTarget"/></constructor-arg> 
</object> 

<object id="swappable" 
    type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> 
    <property name="targetSource"> 
     <ref local="swapper"/> 
    </property> 
</object> 
+0

Hmm vous avez raison, l'instanciation paresseuse aidé bien sûr.Laissez-moi vous décrire ce que je veux faire: j'ai plusieurs contextes pour différents clients. Lorsque je tire l'objet d'un contexte, je veux ajouter un client "id" (objet nhibernate simple) à l'objet tiré (service) et tous les autres services qui sont référencés à partir de l'objet tiré. – rrejc

+0

Désolé, je ne comprends toujours pas ce que vous essayez de faire. Essayez d'être précis sur les objets qui sont des singletons et les références dont vous avez besoin entre les objets. Vous trouverez peut-être utile d'utiliser l'injection de méthode, il est conçu pour lisser les limites entre les objets de différentes étendues. Voici la documentation: http://www.springframework.net/docs/1.3.0-RC1/reference/html/objects.html#objects-method-injection –

0

Pourquoi n'utilisez-vous pas scope="singleton" si vous voulez un singleton ou est-ce que quelque chose me manque?

+0

Que voulez-vous dire par là? Pour ajouter scope = "singleton" à la définition d'objet comme ceci: Ceci n'est pas possible seulement être une application, une session ou une demande). Si vous voulez dire singleton = "true", cela n'a pas besoin d'être spécifié car c'est le comportement par défaut AFAIK. La chose est que je veux assigner un identifiant à tous les services qui sont créés d'usine. – rrejc

+0

scope = "singleton" est valide. Consultez la documentation du printemps: http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes –

+0

Désolé si je ne l'ai pas dit explicitement, mais j'utilise le printemps .net (où cela, comme dit, n'est pas une valeur valide). – rrejc

1

Je ne suis pas sûr de ce que l'énoncé du problème est exactement (jamais utilisé Spring pour. NET). Mais si vous voulez ce que Don Kirkby suggère, vous devriez chercher TargetSources dans la documentation de référence (en supposant que l'implémentation .NET en a aussi).

+0

Merci, je n'avais jamais couru sur des sources cibles auparavant. Je ne sais pas si cela aide l'affiche originale, mais j'apprécie l'info. –