Compte tenu de la mise en œuvre ci-dessous dans le château de windsor 3.4.0:Château Windsor UsingFactoryMethod avec LifestyleTransient
public class ExampleInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<FailoverDatabaseConnectionExecutor>()
.ImplementedBy<FailoverDatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<DatabaseConnectionExecutor>()
.ImplementedBy<DatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
UsingFactoryMethod(CreateDatabaseConnectionExecutor)
.LifestyleTransient()
.IsDefault());
}
private static IDatabaseConnectionExecutor CreateDatabaseConnectionExecutor(IKernel kernel)
{
var configurationRepository = kernel.Resolve<IConfigurationRepository>();
return configurationRepository.GetSetting(ConfigurationSettings.DatabaseFailoverEnabled,() => false)
? (IDatabaseConnectionExecutor)kernel.Resolve<FailoverDatabaseConnectionExecutor>()
: kernel.Resolve<DatabaseConnectionExecutor>();
}
}
Le cadre est de retour l'exception suivante:
instance FailoverDatabaseConnectionExecutor du composant lié tardif IDatabaseConnectionExecutor est déjà être suivi. La méthode usine fournissant des instances du composant réutilise des instances, mais le style de vie du composant est Transitoire, ce qui nécessite une nouvelle instance chaque fois. Dans la plupart des cas, il est conseillé pour la méthode d'usine de ne pas gérer la réutilisation des instances, mais de choisir un style de vie qui le fait de manière appropriée. Sinon, si vous ne souhaitez pas Windsor pour suivre les objets provenant de l'usine changer votre regustration à « .UsingFactoryMethod (yourFactory, managedExternally: vrai) »
Il en résulte la chaîne de dépendance ne pas résoudre et une valeur nulle sur l'injection de propriété sur notre contrôleur.
Ce que nous essayons d'obtenir est un commutateur sur la résolution basée sur la valeur de configuration ConfigurationSettings.DatabaseFailoverEnabled
. Nous voulons que cela se produise de manière transitoire à la fois sur l'usine et sur les types résolus sous-jacents.
De l'erreur, il semblerait cela est impossible, notre question est de savoir comment réaliser une mise en œuvre de l'usine de style tout en maintenant un cycle de vie transitoire sur les deux FailoverDatabaseConnectionExecutor
et DatabaseConnectionExecutor
EDIT:
Après passer un peu de temps à enquêter plus loin, cela semble être un problème lié à l'un des objets de ma chaîne de dépendance. Lorsque l'un des objets implémente IDisposable, cette erreur se produit lorsqu'il est utilisé conjointement avec UsingFactoryMethod.
Tenir compte de la ci-dessous (simplifié) exemple:
public class ServiceInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ISomeConnectionService>()
.ImplementedBy<SomeConnectionService>()
.LifestyleTransient()
.IsDefault());
container.Register(
Component.For<FailoverDatabaseConnectionExecutor>()
.ImplementedBy<FailoverDatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
.UsingFactoryMethod(CreateDatabaseConnectionExecutor)
.LifestyleTransient()
.IsDefault());
}
private static IDatabaseConnectionExecutor CreateDatabaseConnectionExecutor(IKernel kernel)
{
return kernel.Resolve<FailoverDatabaseConnectionExecutor>();
}
}
public interface IDatabaseConnectionExecutor
{
}
public class SomeConnectionService : ISomeConnectionService, IDisposable
{
public SomeConnectionService()
{
}
public void Dispose()
{
}
}
public interface ISomeConnectionService
{
}
public class FailoverDatabaseConnectionExecutor : IDatabaseConnectionExecutor
{
private readonly ISomeConnectionService _someConnectionService;
public FailoverDatabaseConnectionExecutor(ISomeConnectionService someConnectionService)
{
_someConnectionService = someConnectionService;
}
}
Retrait IDisposable de SomeConnectionService injectera correctement la chaîne de dépendance.
Est-ce que quelqu'un sait pourquoi c'est le cas dans Castle Windsor?
Veuillez essayer Release() 'the configurationRepository avant de retourner de votre méthode d'usine. Lorsque vous utilisez Castle, vous devriez avoir l'habitude d'appeler explicitement Release() pour tout ce que vous avez résolu(). –