SORU
3 Mart 2011, PERŞEMBE


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!)

http://blogs.microsoft.co.il/blogs/gilf/archive/2010/05/18/how-to-manage-objectcontext-per-request-in-asp-net.aspx

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:

  1. http://cgeers.wordpress.com/2009/02/21/entity-framework-objectcontext/#objectcontext
  2. http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
  3. attaching linq to sql datacontext to httpcontext in business layer
  4. http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
  5. http://msdn.microsoft.com/en-us/library/bb738470.aspx

CEVAP
4 Mart 2011, Cuma


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Bogdan Gabriel

    Bogdan Gabri

    5 Aralık 2006
  • Charles Renaud

    Charles Rena

    10 Kasım 2007
  • FPSRussia

    FPSRussia

    19 NİSAN 2010