I am working on a ASP.NET MVC 5.0 web application. I am experiencing some issues from shared hosting server. They say, worker process is limited to 150MB and my application is taking beyond. So, firstly I wanted to work with garbage collection to reduce the load.
In my DAL I have inherited IDisposable to a class where I have customized methods and made a call to destructor at the end of it.
public class DbAccessSupport : IDisposable
{
public void Dispose()
{
//cmd.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
cmd.Dispose();
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~DbAccessSupport()
{
Dispose(false);
}
}
public class MasterWithADO
{
public int DALPostChatMsg(string xml)
{
using (DbAccessSupport DbAccessSupportForSP = new DbAccessSupport(true))
{
DbAccessSupportForSP.CommandText = "sp_PostSingleChatMsg";
DbAccessSupportForSP.AddParameter("#inputXml", xml);
return DbAccessSupportForSP.ExecuteNonQuery();
}
}
}
Is this the best way to implement collection and compaction for 3 -tier architecture. If yes then I would have to implement this in BAL and Application Layer also, that is going to add processing overhead quite high.
Related
Wondering if I could get a little guidance here. On DbContext's MSDN page (http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext%28v=vs.103%29.aspx), it states: "Represents a combination of the Unit-Of-Work and Repository patterns and enables you to query a database and group together changes that will then be written back to the store as a unit."
My understanding of the repository pattern is it provides an abstraction over your data persistence layer. How can a concrete implementation of something coupled to EF be considered an abstraction?
Also, how would I leverage it as a Unit of Work pattern? Currently, my Unit of Work has an ObjectContext property, and one properties for each of my repos:
public class UnitOfWork : IUnitOfWork
{
private TPSEntities _context = new TPSEntities();
private ICustomerRepository _customerRepository;
private IUsersRepository _UsersRepository;
public ICustomerRepository CustomerRepository
{
get
{
if (_customerRepository == null)
{
_customerRepository = new CustomerRepository(_context);
}
return _customerRepository;
}
}
public IUsersRepository UsersRepository
{
get
{
if (_UsersRepository == null)
{
_UsersRepository = new UsersRepository(_context);
}
return _UsersRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
public void Save(string storedProcedure)
{
_context.SaveChanges();
//_context.ExecuteStoreCommand
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
I then inject my Unit of Work object into my controller via DI, and away I go.
Is there a better way to do this with DbContext?
Thanks,
Chris
Actually, DbContext is an abstraction over the database - there are several flavors of the SQL engines from Microsoft that all work out-of-the-box with EF, and if you use EF in your code the only thing you have to change to switch between the engines is the connectionstring.
That said, it is not unusual to want yet another abstraction, this time over the ORM tool - EF, in your case. Most guides, blog posts etc I find that demonstrate the repository pattern, do this by abstracting the ORM tool as well. So do you, in the code you provide.
I guess it boils down to your definition of "database layer" and "repository" - and even though I'm sure there are stringent definitions in the literature, the definitions are not consistent across the internet. (Surprised? :P)
Busy doing some work on an existing web app and concerned about the thread safety of the ObjectContext being used in a BaseRepository class. The code that is causing my spidey sense to tingle is:
// within base repository
private SiteDataContext context;
public SitepDataContext Context
{
get
{
if (context == null)
context = new SiteDataContext();
return context;
}
}
// inherited repository
public class InheritedRepository1 : BaseRepository
{
public SomeEntity Get()
{
var something = Context.SomeEntity.First();
}
}
public class InheritedRepository2 : BaseRepository
{
public SomeOtherEntity Get()
{
var something = Context.SomeOtherEntity.First();
}
}
My understanding is:
the ObjectContext is not threadsafe and may be shared across threads in this instance.
A single objectcontext should be used across an http request. Multiple objectcontexts are being created from various repositories to render a page.
The objectcontext does not seem to be closed, disposed off at any point in the http request. This could be a problem if transactions are being used and transactions are committed from threads than did not begin them.
Would appreciate any feedback on these 3 points above as my experience is primarily based on NHibernate.
You could implement the Repository and Unit of Work patterns.
Considering the IIS uses Thread pool to manage requests, my solution is to create one and only one ThreadStatic DataContext for each request, and clear it after request ending.
public class DataContextManager
{
[ThreadStatic]
private static MyDataContext dataContext = null;
public static MyDataContext GetContext()
{
if (dataContext == null)
{
dataContext = new MyDataContext();
}
return dataContext;
}
public static void Clear()
{
dataContext = null;
}
}
While very familiar to Webforms and Linq, I am a novice to the ASP.NET MVC and NHibernate World. I have been working through a project using Bob Cravens' examples. My application is mostly reads and non-sequential writes, so typically I would not use a transactions. But to implement the Unit-of-Work pattern, all my research including Ayende's blog says I should.
The problem I have is this -
Ninject creates a Session and Opens a Transaction.
Ninject injects repositories into services, and services into controllers.
I make some changes to the properties and children of an object and save on the aggregate root. This calls Transaction.Commit (works fine, as expected)
In another method later in the controller, I try to save a separate object
The second call fails because the transaction is no longer active.
I'm thinking of adding a bool "CommitNeeded" to the UnitOfWork which would be set by my Save() method and conditionally trigger a Commit() on UnitOfWork.Dispose(). Is this a good idea?
Should I remove the transaction infrastructure? Should I change my Commit()'s to Flush()'s?
Any advice that would help fix my anti-pattern would be appreciated.
In response to the comments - I guess I don't mind if they happen together or separate. There are two things going on. The first one changes a "Customer" object, and then saves it. The second makes a logging entry which then calls the same "Save" method.
var Customer = ServiceLayer.GetCustomer(...);
Transmogrify(Customer, Customer.Children, Widgets, ...);
ServiceLayer.Save(Customer)
ServiceLayer.RecordEvent(Customer, "Customer was frobbed")
where LogEvent looks like
public void RecordEvent(Customer customer, int eventTypeId, string description)
{
...
Save(customer);
}
The RecordEvent method has its own "save" because it is called from other controllers that do no data changes. I believe the Save call doesn't belong in either of those places. The question is, where? The Dispose() method of the Service Layer? or a Filter like the other users suggested?
Using ASP.NET MVC, I use an action filter to bind the transaction scope to the controller action execution lifecycle. This works great most of the time, but you have to be cautious not to keep transactions open too long.
public class UnitOfWorkActionFilter : ActionFilterAttribute
{
public IUnitOfWork UnitOfWork { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
UnitOfWork.Start();
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception == null)
{
UnitOfWork.Commit();
}
else
{
UnitOfWork.Rollback();
}
UnitOfWork.Dispose();
base.OnActionExecuted(filterContext);
}
}
In my case I'm using property injection via a custom ControllerActionInvoker to get the IUnitOfWork dependency into the ActionFilterAttribute.
I'm using for that an http module. I get the transaction at the beginning of http request and terminate it on the end of http request :
public class UnitOfWorkModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
}
private void context_BeginRequest(object sender, EventArgs e)
{
IUnitOfWork instance = UnitOfWorkFactory.GetDefault();
instance.Begin();
}
private void context_EndRequest(object sender, EventArgs e)
{
IUnitOfWork instance = UnitOfWorkFactory.GetDefault();
try
{
instance.Commit();
}
catch
{
instance.RollBack();
}
finally
{
instance.Dispose();
}
}
}
My unit of work factory it's just a Func initialized while registering types in IoC container :
public class UnitOfWorkFactory
{
public static Func<IUnitOfWork> GetDefault;
}
Initialization (for my case StructureMap) :
UnitOfWorkFactory.GetDefault = () => container.GetInstance<IUnitOfWork>();
And then you register you in UnitOfWorkModule web.config
<httpModules>
<add name="UnitOfWorkModule" type="UI.UnitOfWorkModule, UI" />
</httpModules>
I'm trying to build a real-world app using this tutorial as a basis for the framework. I understand MVC, but am new to the whole IOC/NHibernate world. After reading a few Q&A here on SO, I am thinking of adding a Service layer between the controller and the repository as I'll be adding some business rule validations down the line.
The source on github also has a 'ServiceInstaller' that proved really useful as it allows me to add any services to the application i.e.
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly().Pick()
.If(Component.IsInSameNamespaceAs<SectionService>())
.Configure(c => c.LifeStyle.Transient)
.WithService.DefaultInterface());
}
My question is specific to this tutorial, and its basically that I'm not sure if the ISession (which is the UoW) is passed from the Service layer to the Repository, or if there's another approach.
Here's what I have so far:
// Controller
public class SectionsController : Controller
{
public ILogger Logger { get; set; }
private readonly ISectionService sectionService;
public SectionsController(ISectionService sectionService)
{
this.sectionService = sectionService;
}
public ActionResult Index()
{
return View(sectionService.FindAll());
}
// other action methods
}
// Service Layer
public class SectionService : ISectionService
{
private ISectionRepository repository;
public SectionService(ISession session)
{
this.repository = new SectionRepository(session);
}
public IQueryable<Section> FindAll()
{
return repository.FindAll();
}
// other methods
}
// Repository
public class SectionRepository : ISectionRepository
{
private readonly ISession session;
public SectionRepository(ISession session)
{
this.session = session;
}
public IQueryable<Section> FindAll()
{
return session.QueryOver<Section>().List().AsQueryable();
}
// other CRUD methods
}
Is this correct way to implement this?
There's a reason why the sample app is implemented that way. Well, actually two reasons.
First reason that it is relatively simple and there's not enough logic to warrant a separate layer yet.
Second is, that this kind of controller --> service --> repository --> ISession abstractions are pointless and add nothing to the table. Only thing they do is increase the complexity of the app and amount of work you do for no benefit.
Ayende has a nice, recent, series of blogposts about it which I highly recommend. (here's the first of them, followed by few others).
What sorts of real-world requirements do you have that would warrant those two additional layers?
In closing, YAGNI and KISS.
I have implemented a service which uses a DAOFactory and a NHibernate Helper for the sessions and transactions. The following code is very much simplified:
public interface IService
{
IList<Disease> getDiseases();
}
public class Service : IService
{
private INHibernateHelper NHibernateHelper;
private IDAOFactory DAOFactory;
public Service(INHibernateHelper NHibernateHelper, IDAOFactory DAOFactory)
{
this.NHibernateHelper = NHibernateHelper;
this.DAOFactory = DAOFactory;
}
public IList<Disease> getDiseases()
{
return DAOFactory.getDiseaseDAO().FindAll();
}
}
public class NHibernateHelper : INHibernateHelper
{
private static ISessionFactory sessionFactory;
/// <summary>
/// SessionFactory is static because it is expensive to create and is therefore at application scope.
/// The property exists to provide 'instantiate on first use' behaviour.
/// </summary>
private static ISessionFactory SessionFactory
{
get
{
if (sessionFactory == null)
{
try
{
sessionFactory = new Configuration().Configure().AddAssembly("Bla").BuildSessionFactory();
}
catch (Exception e)
{
throw new Exception("NHibernate initialization failed.", e);
}
}
return sessionFactory;
}
}
public static ISession GetCurrentSession()
{
if (!CurrentSessionContext.HasBind(SessionFactory))
{
CurrentSessionContext.Bind(SessionFactory.OpenSession());
}
return SessionFactory.GetCurrentSession();
}
public static void DisposeSession()
{
var session = GetCurrentSession();
session.Close();
session.Dispose();
}
public static void BeginTransaction()
{
GetCurrentSession().BeginTransaction();
}
public static void CommitTransaction()
{
var session = GetCurrentSession();
if (session.Transaction.IsActive)
session.Transaction.Commit();
}
public static void RollbackTransaction()
{
var session = GetCurrentSession();
if (session.Transaction.IsActive)
session.Transaction.Rollback();
}
}
At the end of the day I just want to expose the IService to ASP.NET MVC/Console application/Winform. I can already use the Service in a console application but would like to improve it first. I guess the first improvement would be to inject the interfaces INHibernateHelper and IDAOFactory via castle. But I think the problem is that the NHibernateHelper might cause problems in a asp.net context where NHibernateHelper should run according to the 'Nhibernate session per request' pattern. One question I have is whether this pattern is determined by the nhibernate config section (setting current_session_context_class = web) or can i control this via castle somehow?
I hope this makes sense. The final aim is just to expose THE IService.
Thanks.
Christian
You have two choices..
1) Host it in WCF. This allows you access from any source you want.
2) Abstract away everything that's specific to how the code is being used. In our system for instance we use our own Unit Of Work implementation which is stored differently based on where the code is running. A small example would be storing something using the WCF call context vs. the current thread.