2009-05-13 6 views
4

J'ai un projet où ma couche de gestion est construite en utilisant DI, mais j'essaie d'aller plus loin et d'utiliser Windsor pour gérer la construction d'objets.Castle Windsor: Comment enregistrer une méthode d'usine, lorsque le type sous-jacent n'est pas accessible à mon assemblage?

Disons simplement que j'ai une couche de données pré-existantes (que je ne veux pas modifier), qui est accessible via l'interface suivante:

interface IDataFactory { 
    IDataService Service { get; } 
} 

Une série de cours dans ma couche d'affaires dépendent des services exposés par IDataFactory:

IFactory factory = DataFactory.NewFactory(); 
IBusinessService service = new ConcreteBusinessService(factory.Service); 

Je comprends que pour vous inscrire IBusinessService au conteneur du château de Windsor, j'utiliser un code similaire à ceci:

IWindsorContainer container = new WindsorContainer(); 
container.AddComponent("businessService", typeof(IBusinessService), typeof(ConcreteBusinessService)); 

Mais pour la vie de moi, je ne peux pas comprendre comment enregistrer les services de ma couche de données, en utilisant mon objet d'usine existant. Essentiellement, je voudrais dire:

container.AddComponent("dataService", typeof(IDataService), factory.service); 

Windsor me semble vouloir dire container.AddComponent ("DATASERVICE", typeof (IDataService), typeof (SomeConcreteDataService)), mais dans ce cas, ConcreteDataService est interne à cet assembly, et n'est donc pas accessible dans le mien.

Comment procéder pour câbler le service de données, étant donné que SomeConcreteDataService n'est pas connu de mon assembly?


This question est très semblable à la mienne, sauf dans mon cas, la AddComponent ("calculatrice", typeof (ICalcService), typeof (CalculatorService), "Création"); l'appel ne fonctionnerait pas - CalculatorService serait interne à un autre assemblage, non disponible pour l'assemblage du conteneur.

Répondre

13

Utiliser Windsor 2.0:

[TestFixture] 
public class WindsorTests { 
    public interface IDataService {} 

    public class DataService: IDataService {} 

    public interface IDataFactory { 
     IDataService Service { get; } 
    } 

    public class DataFactory: IDataFactory { 
     public IDataService Service { 
      get { return new DataService(); } 
     } 
    } 

    [Test] 
    public void FactoryTest() { 
     var container = new WindsorContainer(); 
     container.AddFacility<FactorySupportFacility>(); 
     container.AddComponent<IDataFactory, DataFactory>(); 
     container.Register(Component.For<IDataService>().UsingFactory((IDataFactory f) => f.Service)); 
     var service = container.Resolve<IDataService>(); 
     Assert.IsInstanceOfType(typeof(DataService), service); 
    } 
} 

Voir la fluent API wiki page pour plus d'informations.

0

Vous l'avez. La réponse est, vous n'avez pas besoin de vous soucier du type de mise en œuvre:

IWindsorContainer container = new WindsorContainer(); 
    container.AddFacility("factories", new FactorySupportFacility()); 
    container.AddComponent("standard.interceptor", typeof(StandardInterceptor)); 
    container.AddComponent("factory", typeof(DataFactory)); 

    MutableConfiguration config = new MutableConfiguration("dataService"); 
    config.Attributes["factoryId"] = "factory"; 
    config.Attributes["factoryCreate"] = "get_Service"; 
    container.Kernel.ConfigurationStore.AddComponentConfiguration("dataService", config); 
    container.Kernel.AddComponent("dataService", typeof(IDataService)); 

    IDataService dataService = (IDataService) container["dataService"]; 

J'ai eu un « whoa » moment où je l'ai vu exécuter avec succès, parce que je ne l'avais pas passé dans le type de mise en œuvre spécifique au noyau .AddComponent()

Questions connexes