J'essaie d'obtenir la construction de l'objet comme indiqué ci-dessous, ce qui crée un nouveau DbContext
dans l'utilisation et est donc éliminé en quittant la portée d'utilisation. Donc, comme indiqué ci-dessous, j'ai créé deux objets de processeur dans deux portées distinctes. Je veux y parvenir en utilisant Castle Windsor
.Utilisation de Castle Windsor J'ai besoin d'une nouvelle instance d'un objet lors du démarrage d'une nouvelle portée
using (var context = new DbContext())
{
var processor = new Processor(context, new Parser(context, new Logger(context)), new Logger(context));
}
using (var context = new DbContext())
{
var processor = new Processor(context, new Parser(context, new Logger(context)), new Logger(context));
}
J'ai posé une question similaire avant Castle Windsor propogating inline dependencies qui a suggéré d'utiliser les étendues, mais je ne peux pas le faire fonctionner comme je le veux. Voir le programme entier ci-dessous.
using Castle.MicroKernel.Lifestyle;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;
namespace IOCTesting
{
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container
.Register(Component.For<IProcessor>()
.ImplementedBy<Processor>());
container
.Register(Component.For<IParser>()
.ImplementedBy<Parser>());
container
.Register(Component.For<ILogger>()
.ImplementedBy<Logger>());
container.Register(Component.For<DbContext>()
.ImplementedBy<DbContext>()
.LifeStyle
.Scoped());
using (container.BeginScope())
{
var processor = container.Resolve<IProcessor>();
}
using (container.BeginScope())
{
var processor = container.Resolve<IProcessor>();
}
}
}
public class DbContext : IDisposable
{
public void Dispose()
{
Console.WriteLine("DbContext disposed.");
}
}
public class Processor : IProcessor
{
private readonly DbContext _context;
private readonly ILogger _logger;
private readonly IParser _parser;
public Processor(DbContext context, IParser parser, ILogger logger)
{
_context = context;
_parser = parser;
_logger = logger;
}
}
public class Parser : IParser
{
private readonly DbContext _context;
private readonly ILogger _logger;
public Parser(DbContext context, ILogger logger)
{
_context = context;
_logger = logger;
}
}
public class Logger : ILogger
{
private readonly DbContext _context;
public Logger(DbContext context)
{
_context = context;
}
}
public interface IProcessor
{
}
public interface IParser
{
}
public interface ILogger
{
}
}
En sortant de la première container.BeginScope()
la méthode Dispose
sur DbContext
est appelée, mais sur le deuxième appel à conteneur. BeginScope()
La méthode Dispose
n'est pas appelée lors de la sortie de la deuxième étendue.
Cela implique que le conteneur me soit donné la même instance DbContext disposée lorsque le second conteneur. BeginScope()
est appelée. En substance, j'ai besoin que le DbContent
soit transitoire au sein du container.BeginScope()
et le conteneur me donne une nouvelle instance DbContext
sur chaque portée nouvellement créée afin qu'elle soit toujours éliminée lorsque la portée est quittée.
J'espère que cela a du sens.
Merci Andy pour votre explication et vous avez raison. Vous l'avez mentionné dans la réponse à l'autre question, mais dans ma hâte, je n'ai pas digéré complètement ce que vous disiez. L'exemple que j'ai donné est en fait un exemple d'un problème dans notre base de code existante. J'essaie de lire un message hors de la file d'attente et j'ai besoin que le dbcontext soit actif pendant le traitement du message. Certains des objets qui sont utilisés pour traiter le message sont des Singletons et, comme vous le dites correctement, ce sont ces objets qui font référence au dbcontext. Je devrai refactoriser le code pour supporter ce scénario. – dezzy