MVC, EF - DataContext singleton-Web-İstek Başına örnek Birlik içinde
Veri erişimi için Varlık Çerçevesi kullanarak nerede olduğumu 3 web MVC uygulaması var. Ayrıca, tüm Ürün ile ilgili şeyleri ele bulunduğu depo desen, basit bir kullanım yaptık "" ve tüm Kullanıcı ilgili şeyler olarak ele alınır "". UserRepository ProductRepository
Böylece, BİRLİK konteyner, depoların her birinin içine enjekte olan DataContext, tek bir örnek yapmak için kullanıyorum. Google'da hızlı bir arama yapın ve herkes sizi gelecekte bazı bellek sızıntıları verebilir gibi DataContext singleton örneği kullanmak için DEĞİL önerir.
Yani, bu yazıya ilham, her web isteği için DataContext singleton örneği yapıyor cevap (Eğer yanılıyorsam beni düzeltin lütfen!)
Ancak, BİRLİK desteklemiyor "Per-web-istek" ömür yöneticisi. Ama senin için bu işler kendi özel ömür yöneticisi, uygulamak mümkündür. Aslında, bu yazı ele alınmıştır :
Singleton Per Call Context (Web Request) in Unity
Soru şu, şimdi yukarıda yazılan açıklandığı gibi özel ömür yöneticisi uyguluyorum, ama eğer bu iş böyle ise emin değilim. Ayrıca datacontext örneği sunulan çözümün bertaraf nerede olduğunu merak ediyorum? Bir şey eksik muyum?
Aslında benim çözmenin daha iyi bir yolu""? sorunu var
Teşekkürler!
* * * * Benim uygulama hakkında bilgi eklendi
Aşağıdaki benim Küresel dan parçacıkları.asax, Kumanda ve Depo. Bu benim uygulama net bir görüntü sağlar.
Global.asax
var container = new UnityContainer();
container
.RegisterType<ProductsRepository>(new ContainerControlledLifetimeManager())
.RegisterType<CategoryRepository>(new ContainerControlledLifetimeManager())
.RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString)
Denetleyicisi
private ProductsRepository _productsRepository;
private CategoryRepository _categoryRepository;
public ProductsController(ProductsRepository productsRepository, CategoryRepository categoryRepository)
{
_productsRepository = productsRepository;
_categoryRepository = categoryRepository;
}
public ActionResult Index()
{
ProductCategory category = _categoryRepository.GetProductCategory(categoryId);
.
.
.
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_productsRepository.Dispose();
_categoryRepository.Dispose();
}
Ürün Depo
public class ProductsRepository : IDisposable
{
private MyEntities _db;
public ProductsRepository(MyEntities db)
{
_db = db;
}
public Product GetProduct(Guid productId)
{
return _db.Product.Where(x => x.ID == productId).FirstOrDefault();
}
public void Dispose()
{
this._db.Dispose();
}
Kumanda Fabrika
public class UnityControllerFactory : DefaultControllerFactory
{
IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, String.Format("The controller for path '{0}' could not be found"
"or it does not implement IController.",
requestContext.HttpContext.Request.Path));
}
return _container.Resolve(controllerType) as IController;
}
}
Ek bilgi Merhaba, rastlamak ek bağlantılar ile ilgili sorun ve çözüm önerileri ile ilgili olarak yayınlayacağız:
- http://cgeers.wordpress.com/2009/02/21/entity-framework-objectcontext/#objectcontext
- http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
- attaching linq to sql datacontext to httpcontext in business layer
- http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
- http://msdn.microsoft.com/en-us/library/bb738470.aspx
CEVAP
Evet 34* *ve istek başına bir bağlam kullanın. Ayrıca ortak bir bağlam neden olan o yazı sorular tüm problemleri görmek için bağlı kontrol edebilirsiniz.
Şimdi Birlik hakkında. Fikir ama uygulaması sağlanan bence çalışır birden fazla nesne için çalışmaz. PerHttpRequestLifetimeManager
doğrudan kullanmanız gerekir:
public class PerHttpRequestLifetime : LifetimeManager
{
// This is very important part and the reason why I believe mentioned
// PerCallContext implementation is wrong.
private readonly Guid _key = Guid.NewGuid();
public override object GetValue()
{
return HttpContext.Current.Items[_key];
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[_key] = newValue;
}
public override void RemoveValue()
{
var obj = GetValue();
HttpContext.Current.Items.Remove(obj);
}
}
Birlik sizin için bağlam imha edecektir unutmayın. Ayrıca varsayılan UnityContainer
uygulama asla RemoveValue
yöntemi unutmayın.
Eğer uygulama Resolve
tek arama tüm depoları örneğin denetleyicileri kurucu depoları örnekleri alır ve denetleyicileri çözme () çözerse bu ömür yöneticisi gerekmez. Böyle bir durumda kullanımı bu yap-(Birlik 2.0) 16**.
Düzenleme:
Ben UnityContainer
sağlanan yapılandırma oldukça büyük bir sorun. ContainerControllerLifetimeManager
ile her iki depoları ediyorsunuz. Bu ömür yöneticisi konteyner ömür boyu başına Tek örneği anlamına gelir. Hem depoları yalnızca bir kez ve bir örneği saklanır ve sonraki aramalar için yeniden oluşturulacak demektir. Bu yüzden ne ömür MyEntities
atadınız mı önemli değil. Depoları için' sadece bir kez adı verilecek kurucular. enjekte edilir Her iki havuzları MyEntities
hala tek örnek = AppDomain
sizin bütün ömrü boyunca tek örnek kullanacaklar kendi inşaat sırasında oluşturulan kullanır. Bunu başarmak için en kötü senaryodur.
Yapılandırmanızı bu şekilde yeniden yazmak:
var container = new UnityContainer();
container
.RegisterType<ProductsRepository>()
.RegisterType<CategoryRepository>()
.RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString);
Bu neden yeterli mi? Repsitories bağlı olan denetleyici çözümlemek, ama hiç depoyu örneği her arama için yeni bir örneğini oluşturur varsayılan TransientLifetimeManager
kullanabilirsiniz bir kez daha ihtiyaç var. Bu depo yüzünden kurucu denir ve MyEntities
örnek çözülmelidir. Ama birden fazla havuzları * = ^ * 25 ile ayarlamak, bu yüzden bu örneği lazım . denetleyici her çözme MyEntities
sadece bir örnek oluşturur.
Tek Başına bir Çağrı İçeriği (Web İste...
HTTP Node.js Express içinde İstek OLSU...
Bir şekilde birden çok öğe oluşturmak ...
Nasıl istek nesnesine erişmek veya bir...
İçinde döngüler JavaScript kapatma – b...