ASP.NET: Implementing Init and Dispose methods - asp.net

Can an ASP.NET web application have only one Init and one Dispose method or can I implement these per class for those which I want to associate such methods?
More specifically I have Customer component and a CustomerRecord classes and would like to implement Init and Dispose methods in both of them.
What is the proper way to do this?
Requirement:
I want to have independent Init and Dispose methods for each aforementioned class.

For classes that should be disposable, by exposing a public Dispose method, the IDispsable interface must be implemented for 'disposability' to be effective out of the scope of explicit user disposal. This has been covered many times in many places, including here, for example:
public class Customer : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SupressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//dispose of managed resources
}
//dispose of unmanaged resources
}
~Customer()
{
Dispose(false);
}
}
Note that the destructor (the method starting with the tilde ~) may not be necessary, but read the details from the answer I linked above for clarity on the situation of what and why - this just answers your question directly.
As for an Init method, are you referring to a constructor?
If so, then look at the destructor in the above example; a constructor (or initialiser) can be defined in the same way minus the tilde and, generally, plus an explicit access modifier (public, private, et cetera), for example:
public class Customer
{
public Customer()
{
}
}

You can create a base class with the Init and Dispose method as you wish and then make the other classes to inherit from it. For example:
public class BaseClass
{
public void Init()
{
//Some code
}
public void Dispose()
{
//Some code
}
}
public class Customer : BaseClass
{
//Some code
}
That might help you.

Related

Unit of work pattern not allowing me to create db context without options

I am using ef core and I am trying to implement the repository pattern as part of best practices. But I am we bit confused on the context normally I would create the context in the and inject
HomeController(WarehouseDBContext _context)
I have created my unitOfWork Class as suggested by the docs here
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application#creating-the-unit-of-work-class
However I am tad confused. It's expecting options here which is normally handled on the controller.
My UnitOfWork class
public class WarehouseUnitOfWork : IDisposable
{
private WarehouseDBContext context = new WarehouseDBContext();
private WarehouseRepository<StockItem> stockRepository;
public WarehouseRepository<StockItem> StockRepoistry
{
get
{
if (this.stockRepository == null)
{
this.stockRepository = new WarehouseRepository<StockItem>(context);
}
return stockRepository;
}
}
public void Save()
{
context.SaveChanges();
}
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);
}
}
But here it is complain that it expect options which would I presume contain the connection string. I am trying to decouple my code from EF so that If I want to upgrade in the future will be easier. My WareshouseDBContext is describe below
As you can see it is expecting options. What should I pass through here?
namespace WareHouseDal.Dal {
public class WarehouseDBContext : IdentityDbContext<ApplicationUser> {
public WarehouseDBContext(DbContextOptions<WarehouseDBContext> options)
: base(options) {
}
public DbSet<WarehouseCrm> Warehouse { get; set; }
public DbSet<Company> Companies { get; set; }
}
}
When I used to create my context before I just used the singleton pattern of
private readonly WarehouseDBContext _context;
Is their something else I need to do to allow it to accept the creation of the context on the unit of work level.
Error being given is
You shouldn't create a DbContext manually. Why not injecting the DbContext in your UOW class? Then the DI will manage the life cycle of the db context. To be honest I am not a fan of adding a UOW wrapper around EF which already implements the UOW pattern.
I would recommend you to see both talks, it will change the way you structure apps forever:
https://www.youtube.com/watch?v=5OtUm1BLmG0&ab_channel=NDCConferences
https://www.youtube.com/watch?v=5kOzZz2vj2o&t=3s&ab_channel=NDCConferences
Another amazing talk about EF Core details: https://www.youtube.com/watch?v=zySHbwl5IeU&ab_channel=NDCConferences
If you want to stick with Repository pattern, please check Ardalis repository with a clear example: https://github.com/ardalis/CleanArchitecture
I agree Ardalis repository is a great tutorial/example, in case if anyone want a lite solution to implement the Repository and Unit of Work Patterns in EF 5/EF 6.
you may check out the below one, I tested it would work in EF Core 6
https://pradeepl.com/blog/repository-and-unit-of-work-pattern-asp-net-core-3-1/

controllers, services and unit of work - should I really dispose database context?

Based on this article: http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Should I really dispose context?
For example I have controller with dispose method:
public class BlogController : Controller
{
private readonly INotesService _notesService;
public BlogController(INotesService notesService)
{
_notesService = notesService;
}
protected override void Dispose(bool disposing)
{
_notesService.Dispose();
base.Dispose(disposing);
}
}
So my controller call dispose method from service:
public class NotesService : INotesService
{
private readonly IUnitOfWork _unitOfWork;
public NotesService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public void Dispose()
{
_unitOfWork.Dispose();
}
}
And service call dispose method from unit of work:
public class UnitOfWork : IUnitOfWork
{
private DatabaseContext context = new DatabaseContext();
private INotesRepository notesRepository;
public INotesRepository NotesRepository
{
get
{
if (this.notesRepository == null)
{
this.notesRepository = new NotesRepository(context);
}
return notesRepository;
}
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
In each controller I must remember to call Dispose method. What is more, if my controller uses many services I have to remember to call Dispose method on each service in controller method called also Dispose.
So should I really dispose database context? Maybe it isn't necessary.
It's not strictly necessary in the sense that the garbage collector will eventually come behind you can clean up after you, but it's still good practice to explicitly dispose of anything you no longer need. The controller is instantiated and destroyed for each request, so if you fail to dispose of the resources you accumulated, then you're effectually leaking memory in the interim period between the controller's teardown and the next GC cycle. If you're fielding a ton of requests, that can potentially bring things to a grinding halt if the memory drain adds up faster than deallocation. Depending on the amount of RAM installed on your server, you also may end up paging to the hard disk at times, which will really kill application performance.
Long and short, just follow best practices and dispose of your resources properly. Then, you don't have to worry about whether or not it will eventually be a problem, as it never will be.
For what it's worth, you can allay some of the shaving-a-yak work in this by utilizing a good dependency injection framework. A DI container will manage the lifetimes of your objects and handle disposing of them appropriately. It's kind of cheating, but since dependency injection is good practice, anyways, you might as well take advantage of it.

ASP.NET MVC - Unit Testing Override Initialize Method

I've got an abstract class shown below which gets inherited by all the other controllers. Is it possible to test this method at all? Btw, I'm trying to use MOQ but no luck. If you could help me will be much appreciated:
public abstract class ApplicationController : Controller
{
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
//do some stuff here
}
}
If you take a look at the source code of base Initialize method you will find out that what it does is that it sets up ControllerContext and url stuff. Now, download MvcContrib TestHelper and check out TestControllerBuilder . The builder sets up everything you need in order to have controller context and other stuff which you depend upon.
Ok, we are not over yet - you wanted to test your own override of Initialize right?
TestControllerBuilder doesnt call your Initialize because it does initialization in different way. I suggest you to factor out your custom Initialize() logic out into different method. Then create fake (stub) subclass with public method that calls this factored out protected Initialize. Are you with me?
something like:
public abstract class ApplicationController : Controller
{
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
MyInitialzie()
}
protected void MyInitialize()
{
ControllerContext.XXX // do whatewer you want here. Context is already setted up
}
}
class FakeController: ApplicationController
{
public void CallMyInitialize()
{
MyInitialize();
}
}
Later in test class:
[Test]
public void MyInitializeTest()
{
TestControllerBuilder builder = new TestControllerBuilder();
FakeController controller = new FakeController();
builder.InitializeController(controller);
controller.CallMyInitialize();
//TODO: verification of MyInitialize assumptions
}
Is that clear?

Using castle windsor with interceptors and asp.net

I'm trying to add logging with aspect orientated programming using castle windsor in plain asp.net, i.e. not MVC
I've added a class that implements the IInterceptor interface and an attribute that inherits from Attribute.
public class LogAttribute : Attribute
{
public Level LogLevel { get; set; }
public LogAttribute(Level level)
{
LogLevel = level;
}
}
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
MethodInfo mi = invocation.Method;
LogAttribute[] atts = (LogAttribute[])mi.GetCustomAttributes(typeof(LogAttribute), true);
// if method not marked with InternalUseRestricted attribute, then pass on call
if (atts.Length == 0)
{
invocation.Proceed();
}
else
{
ISeiLogger log = LoggerFactory.GetLogger(mi.DeclaringType.ToString());
//assume only one logging attribute
//log on entry
log.LogEnter(atts[0].LogLevel);
//allow code to continue
invocation.Proceed();
//log on exit
log.LogExit(atts[0].LogLevel);
}
}
}
Now in the global.asax.cs I've added the following:
public partial class Global : System.Web.HttpApplication, IoCProvider
{
private void InitializeIoC()
{
container = new WindsorContainer();
container.Install(new Sei.Aspect.AspectInstaller());
}
public IWindsorContainer Container
{
get { return container; }
}
private static Sei.Logging.ISeiLogger log;
private IWindsorContainer container;
public override void Init()
{
base.Init();
InitializeIoC();
}
and I've created an installer class:
public class AspectInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//container.Register(AllTypes.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IInterceptor>().Configure(component => component.LifeStyle.PerWebRequest));
container.Register(Component.For<IInterceptor>().ImplementedBy<LoggingInterceptor>().LifeStyle.PerWebRequest);
container.Register(Component.For<IInterceptor>().ImplementedBy<InternalUseRestrictedInterceptor>().LifeStyle.PerWebRequest);
container.Register(Component.For<IInterceptor>().ImplementedBy<CachingInterceptor>().LifeStyle.PerWebRequest);
}
}
I now want to add the attribute to some arbitary page's code behind class and some arbitary virtual method, as in
[Log(Level.Info)]
protected string Login(string username, string password)
{
DoSomething();
}
This obviously doesn't work. Do I need to change the way I'm instantiating the page (its a page's code-behind class) to use a container? Or is it the way I'm registering the interceptors? I want to be able to use the interceptors on any class going forward and not have to tell the container about each and every class that I have in my application.
Short answer: it's not possible.
Long answer: due to the way ASP.NET Web Forms works, it doesn't let anyone interfere with the page instantiation. Some claim that using a custom PageHandlerFactory lets you do IoC, but this only lets you set properties after the page has been instantiated, which is simply not enough for proxying.
So runtime proxy libraries such as DynamicProxy or LinFu can't do anything about this. But you may be able to use compile-time aspect weavers, such as PostSharp.
Alternatively, make your code-behind as slim as possible, deferring actual logic to Windsor-managed components.

Can web forms and generic handlers (ashx files) share a common ancestor class (or base page)?

If one has an ASP.net web site whose web forms all inherit from a common base page--which checks things like authentication and redirects when a session has expired, etc--is there a way to use this base class in a ashx handler? I started going down that road by inheriting the base page class in the handler and realized this might not be a recommended practice. Any thoughts on how to avoid code duplication here?
Can this
public class FooHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
become this
public class FooHandler : BasePageClass, IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
I get the following warning, which is what made me reconsider what I was doing:
FooHandler.ProcessRequest(System.Web.HttpContext)
hides inherited member
System.Web.UI.Page.ProcessRequest(System.Web.HttpContext).
To override that implementation, add
the override keyword. Otherwise add
the new keyword.
If you set the parent class ProcessRequest as virtual you can override it in the child class and call the base class method from inside the overridden method.
public abstract class ParentHandler : IHttpHandler, IRequiresSessionState
{
protected WebConnectHandler Context;
public virtual void ProcessRequest(HttpContext context)
{
Context = new WebConnectHandler(context);
}
//...
}
//...
public class ChildHandler : ParentHandler
{
public override void ProcessRequest(HttpContext context)
{
base.ProcessRequest(context);
//the rest of your code
}
}
//...
You are now discovering why the OO guru types always vote for composition over inheritance. Anyhow, doing exactly what you want to do is pretty tricky as, while a System.Web.UI.Page implements IHttpHandler (if I recall correctly) there is lots of internal processing you can't defeat to get back to your own handler.
The easiest fix would be to try and move as many of those functions off the monster base page class into their own classes--or better yet IHttpModules where it makes sense to handle stuff like session expiration--in order to decouple things.

Resources