ASP.NET MVC ayrı bir konu bir görev çalıştırdığınızda görünüyor, SimpleInjector her arama için DBContext yeni bir örneğini oluşturur.
aşağıda
Basit Enjektör v1.5 ait RegisterPerWebRequest
yaşam tarzı davranışı ve örnekleri (HttpContext.Current
boş) bir web isteği bağlamı dışında istendiğinde geçici örneğini döndürmektir. Geçici bir örneğin döndürülmesi, Basit Enjektörde bir tasarım hatasıydı, çünkü bu yanlış kullanımı gizlemeyi kolaylaştırıyor. Version 1.6 of the Simple Injector, geçici olarak hatalı bir örnek döndürmek yerine, kapsayıcıyı yanlış yapılandırdığınız açıkça iletişim kurmak için bir istisna atar.
(örneğin StructureMap için) bazı IoC kütüphaneler başına iplik başına webrequest için karışık yaşam tarzı sahipken
, değil bir
Bu doğrudur Basit Enjektör sahiptir görünüyor Basit Enjektör Birkaç sebepten dolayı karışık yaşam tarzları için yerleşik destek yoktur. Her şeyden önce pek çok insanın ihtiyaç duyduğu egzotik bir özellik. İkincisi, iki ya da üç yaşam tarzını bir araya getirebilirsiniz, böylece melezlerin neredeyse sonsuz bir kombinasyonu olacaktır.Ve son olarak, bunu (güzel) kolayca kendiniz kaydedin.
Eğer Per Thread yaşam tarzları ile Per Web Request karıştırabilirsiniz olsa da, Per Lifetime Scope Web Request Başına mix Ömür Kapsam ile beri açıkça başlatmak ve kapsamını bitirmek (ve kapsam sona erdiğinde DbContext
imha edebiliriz) zaman, muhtemelen daha iyi olurdu .
Simple Injector 2'dan itibaren, Lifestyle.CreateHybrid yöntemini kullanarak herhangi bir sayıda yaşam tarzını kolayca birleştirebilirsiniz. Simple Injector: multi-threading in MVC3 ASP.NET
GÜNCELLEME Güncellemenize Hakkında
:
var hybridLifestyle = Lifestyle.CreateHybrid(
() => HttpContext.Current != null,
new WebRequestLifestyle(),
new LifetimeScopeLifestyle());
// Register as hybrid PerWebRequest/PerLifetimeScope.
container.Register<DbContext, MyDbContext>(hybridLifestyle);
derin biraz, bir göz atmak isteyebilirsiniz Bu konuda gider başka Stackoverflow soru var: İşte bir örnek. Neredeyse ordasın. Arka plan iş parçacığı üzerinde çalışan komutların Ömür Boyu Kapsamı içinde çalışması gerekir, bu nedenle bunu açıkça başlatmanız gerekir. Buradaki hile, yeni iş parçacığına BeginLifetimeScope
numaralı telefonu aramaktır, ancak gerçek komut işleyicisi (ve bağımlılıkları) oluşturulmadan önce. Başka bir deyişle, bunu yapmanın en iyi yolu bir dekoratörün içinde. Bu dekoratör hem yeni iş parçacığı üzerinde komutları çalıştırır beri SOLID ilkeleri bu sınıf Single Responsibility Principle ihlal ettiğini bağıracak savunan
public class AsyncCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> where TCommand : ICommand
{
private readonly Container _container;
private readonly Func<ICommandHandler<TCommand>> _factory;
public AsyncCommandHandlerDecorator(Container container,
Func<ICommandHandler<TCommand>> factory)
{
_container = container;
_factory = factory;
}
public void Handle(TCommand command)
{
ThreadPool.QueueUserWorkItem(_ =>
{
using (_container.BeginLifetimeScope())
{
// Create new handler in this thread
// and inside the lifetime scope.
var handler = _factory();
handler.Handle(command);
}
});
}
}
Purists:
kolay çözüm kapsamını eklemek için AsyncCommandHandlerDecorator
yenilenmesini sağlar ve yeni bir ömür boyu kapsamı başlatır. Bu konuda çok fazla endişelenmem, çünkü arka plan iş parçacığı ile hayat boyu bir alan kurmaya başlamak arasında yakın bir ilişki olduğunu düşündüğümden (zaten bir başkasını kullanamazsın). Ama yine de, kolayca AsyncCommandHandlerDecorator
bakir bırakın ve aşağıdaki gibi yeni LifetimeScopedCommandHandlerDecorator
oluşturabilirsiniz:
public class LifetimeScopedCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> where TCommand : ICommand
{
private readonly Container _container;
private readonly Func<ICommandHandler<TCommand>> _factory;
public LifetimeScopedCommandHandlerDecorator(Container container,
Func<ICommandHandler<TCommand>> factory)
{
_container = container;
_factory = factory;
}
public void Handle(TCommand command)
{
using (_container.BeginLifetimeScope())
{
// The handler must be created inside the lifetime scope.
var handler = _factory();
handler.Handle(command);
}
}
}
AsyncCommandHandlerDecorator
LifetimeScopedCommandHandlerDecorator
sarmak gerektiğinden bu dekoratörler, tabii esas teşkil eden kayıtlı sırası. Bu konuda
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(LifetimeScopedCommandHandlerDecorator<>),
backgroundCommandCondition);
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(AsyncCommandHandlerDecorator<>),
backgroundCommandCondition);
This old Stackoverflow question görüşmelere daha ayrıntılı olarak: Bu LifetimeScopedCommandHandlerDecorator
kaydı şeyden önce gelmeli anlamına gelir. Kesinlikle bir göz atmalısın.
İlgili: http://stackoverflow.com/questions/11041601/simple-injector-multi-threading-in-mvc3-asp-net – Steven
İlgili: http://stackoverflow.com/questions/10304023/simpleinjector-is -bu-sağ-yol-için-kayıt-erkek-posta-ne-i-var – Steven