How Can I guarantee that the Ninject will call the Disposable() automatically? - c#

1)
public class DataProvider : IProvider , IDisposable{
private SqlConnection connection = null;
public DataProvider(string ConnectionString) {
this.connection = new SqlConnection(ConnectionString);
this.connection.Open();
}
public object GetUniqueData(SqlCommand CommandSql){}
public void ExecuteInsertDeleteUpdate(SqlCommand CommandSql){}
public void Dispose(){
if (this.connection != null) {
this.connection.Close();
this.connection.Dispose();
}
}
}
2)
public class ManageBrandDAL : IManageBrandDAL {
private IProvider provider = null;
[Inject]
public ManageBrandDAL (IProvider provider_){
this.provider = provider_;
}
public void RegisterBrand(string a_BrandName){
SqlCommand SQLCommand =
new SqlCommand("INSERT INTO Brand(name) VALUES(#pm_brandname)");
SqlParameter pm_brandname= new SqlParameter();
pm_brandname.ParameterName = "#pm_brandname";
pm_brandname.DbType = DbType.String;
pm_brandname.Value = a_BrandName;
SQLCommand.Parameters.Add(pm_brandname);
this.provider.ExecuteInsertDeleteUpdate(SQLCommand);
}
3)
public class ModuleInfra : Ninject.Modules.NinjectModule
{
public override void Load(){
Bind<IProvider>()
.To<ProvedorDados()
.InTransientScope()
.WithConstructorArgument("ConnectionString", Manage.ConnectionString);
}
}
How can I guarantee that the Ninject Container will call the method Dispose() in DataProvider class after ManageBrandDAL uses the DataProvider object?
Is the InTransientScope() the best lifecycle for this type of situation ? If not, what is more appropriate?

When you bind your DataProvider InTransientScope() it will not be disposed by Ninject, because actually transient scope is no scope at all. Ninject does not tracks objects that are bound in transient scope after it will create one for you.
Ninject disposes instances of objects implementing IDisposable as soon as the underlying scope object is collected by GC (but as as I said this does not work for objects bound to transient scope because there is no such scope object).
You should bind your DataProvider in scope, that is appropriate to your application. It could be:
InRequestScope() for web application (Ninject will dispose instances of objects implementing IDisposable after the end of the http request - don't forget to include OncePerWebRequest module)
InSingletonScope() - instance of object will be re-used for all subsequent requests during the whole lifecycle of application - from my point of view it is not an option for objects holding resources like SqlConnection
InThreadScope() - instance of object will be re-used within the same thread
InScope() - this could be used for creating custom scopes, so according to type of your application you can consider creating your own custom scope suitable to your needs.
There are also interesting extensions for Ninject that provides additional scope definitions: https://github.com/ninject/ninject.extensions.namedscope/wiki
Hints
You don't need to call both Close() and Dispose() on your SqlConnection. Dispose() is enough because it calls Close() internally.
I don't see the whole code, but do not forget to dispose the SqlCommand too.
If you let creating of instances of ManageBrandDAL on Ninject you don't need to use InjectAttribute on its constructor. It will unties you from using specific IOC provider.

Related

how Dispose() works inside my Controller and Repository classes

I am working on asp.net mvc-4 web application and entity framework 5.0. now i am confused on how Dispose is working inside my application. currently i have the following settings:-
-I have a APIRepository class which contain multiple methods that use WebClient() to do external API calls. and i do not define any Dispose method inside this class.
public class APIRepository
{
public string AddTicket(string title, string technichian,string account,string site,string description,string mode,string requestor)
{
//code goes here
using (var client = new WebClient())
{
}
return result;
}
//code goes here
}
-I have a Repository class which contain my data access logic, and it initiate my DbContext, and i define a Dispose method inside this class.
public class Repository
{
private MyEntities my = new MyEntities();
//code goes here...
public void Dispose()
{
my.Dispose();
}
-I have a Controller class, which initiate the two repository classes:-
[RequireHttps]
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
//code goes here
protected override void Dispose(bool disposing)
{
if (disposing)
{
repository.Dispose();
}
base.Dispose(disposing);
}
now i have the following questions about my current project:-
Based on my understanding on how Dispose works, is that when an action method calls a View, then asp.net mvc will automatically calls the Dispose method inside my current Controller class. which in turn calls the Dispose method inside my repository , which will make sure that the database connection is closed. so is my understanding valid ?
in my case do i need to have a Dispose method inside my APIRepository() , which as i mentioned this repository only have WebClient() calls to integrate with 3rd party application, and it will return object or simple string to the action method.??
what are the operations that need to be Disposed? as i know calling a my.Dispose(); inside my repository class will make sure that the database connection is closed.. but are there other operations that need to be disposed? such as initiating a WebClient() or returning a JSON by my action method?
what are the actions other than returning a View will call the Dispose method inside my Controller class ?
If you use dependency injection then none of the classes would be responsible for creating or disposing the dependencies injected into it.
Instead of this:
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
where ServerController creates its dependencies and is responsible for disposing of them, this:
public class ServerController : Controller
{
private readonly Repository _repository;
private readonly APIRepository _apiRepository;
public ServerController(Repository repository, APIRepository apiRepository)
{
_repository = repository;
_apiRepository = apiRepository;
}
Now whatever creates an instance of ServerController is responsible for instantiating those objects and disposing of them. That "whatever" is typically your dependency injection container, like Windsor or Unity. Or even better, in ASP.NET Core it's built in and you don't need to add a separate container.
The short version: The container creates your repository, and if it needs to be disposed, it disposes it. You can even specify details about the lifetime of certain dependencies. If it's not disposable and can be reused then it's a singleton. You can create and dispose a new instance every time you need one. Or you can create a new instance that's tied to a given web request. That request uses it and then it's disposed.
which will make sure that the database connection is closed. so is my understanding valid ?
Your database connection is closed way before the dispose method is called. It would be a very rare circumstance that it is not.
in my case do i need to have a Dispose method inside my APIRepository()
Only if you are managing the disposable of objects at field level instead of a method level.
// The method is disposing of the object
public class NotDisposable
{
public string GetString()
{
string result;
// This is disposed by the time the method exists.
using(var disposable new Disposable)
{
result = disposable.GetString()
}
return result;
}
}
// This class has a field that it needs to dispose
// so it inherites from IDisposable
public class Disposable : IDisposable
{
private bool _isDisposed;
private readonly IDisposable _somethingToManuallyDispose;
public Disposable()
{
somethingToManuallyDispose = new SomethingImplementsIDisposable();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && !_isDisposed)
{
_isDisposed = true;
// Dispose Managed Resources
if (_somethingToManuallyDispose != null)
{
_somethingToManuallyDispose.Dispose();
}
}
}
}
but are there other operations that need to be disposed?
Example above, where you do not Dispose of an object in the method.
what are the actions other than returning a View will call the Dispose method inside my Controller class
That sentence doesn't even make sense. Returning a View does not call Dispose. The MVC/API Pipeline Disposes of the controller after the response is sent to the client, and only if it implements IDisposable.
Please consider reading MSDN - Dispose Pattern and MSDN - Implementing a Dispose Method and MSDN - Using Objects That Implement IDisposable.

Auto Dispose Sql Connections properly

My application is using 3 layers: DAL / Service / UL.
My typical DAL class looks like this:
public class OrdersRepository : IOrdersRepository, IDisposable
{
private IDbConnection _db;
public OrdersRepository(IDbConnection db) // constructor
{
_db = db;
}
public void Dispose()
{
_db.Dispose();
}
}
My service calls the DAL class like this (injecting a database connection):
public class ordersService : IDisposable
{
IOrdersRepository _orders;
public ordersService() : this(new OrdersRepository(new Ajx.Dal.DapperConnection().getConnection()))
{
}
public ordersService(OrdersRepository ordersRepo)
{
_orders = ordersRepo;
}
public void Dispose()
{
_orders.Dispose();
}
}
And then finally within my UI layer, this is how I access my service layer:
public class OrdersController : Controller, IDisposable
{
//
// GET: /Orders/
private ordersService _orderService;
public OrdersController():this(new ordersService())
{
}
public OrdersController(ordersService o)
{
_orderService = o;
}
void IDisposable.Dispose()
{
_orderService.Dispose();
}
}
This all works good. But as you can see, I am relying on IDisposable within every layer. UI disposes service object and then service object disposes DAL object and then DAL object disposes the database connection object.
I am sure there has to be a better way of doing it. I am afraid users can forget to dispose my service object (within UI) and I will end up with many open database connections or worse. Please advise the best practice. I need a way to auto-dispose my database connections OR any other unmanaged resources (files etc).
Your question comes back to the principle of ownership:
he who has ownership of the resource, should dispose it.
Although ownership can be transferred, you should usually not do this. In your case the ownership of the IDbConnection is transferred from the ordersService to the OrdersRepository (since OrdersRepository disposes the connection). But in many cases the OrdersRepository can't know whether the connection can be disposed. It can be reused throughout the object graph. So in general, you should not dispose objects that are passed on to you through the constructor.
Another thing is that the consumer of a dependency often can't know if a dependency needs disposal, since whether or not a dependency needs to be disposed is an implementation detail. This information might not be available in the interface.
So instead, refactor your OrdersRepository to the following:
public class OrdersRepository : IOrdersRepository {
private IDbConnection _db;
public OrdersRepository(IDbConnection db) {
_db = db;
}
}
Since OrdersRepository doesn't take ownership, IDbConnection doesn't need to dispose IDbConnection and you don't need to implement IDisposable. This explicitly moves the responsibility of disposing the connection to the OrdersService. However, ordersService by itself doesn't need IDbConnection as a dependency; it just depends on IOrdersRepository. So why not move the responsibility of building up the object graph out of the OrdersService as well:
public class OrdersService : IDisposable {
private readonly IOrdersRepository _orders;
public ordersService(IOrdersRepository ordersRepo) {
_orders = ordersRepo;
}
}
Since ordersService has nothing to dispose itself, there's no need to implement IDisposable. And since it now has just a single constructor that takes the dependencies it requires, the class has become much easier to maintain.
So this moves the responsibility of creating the object graph to the OrdersController. But we should apply the same pattern to the OrdersController as well:
public class OrdersController : Controller {
private ordersService _orderService;
public OrdersController(ordersService o) {
_orderService = o;
}
}
Again, this class has become much easier to grasp and it doesn't needs to dispose anything, since it doesn't has or took ownership of any resource.
Of course we just moved and postponed our problems, since obviously we still need to create our OrdersController. But the difference is that we now moved the responsiblity of building up object graphs to a single place in the application. We call this place the Composition Root.
Dependency Injection frameworks can help you making your Composition Root maintainable, but even without a DI framework, you build your object graph quite easy in MVC by implementing a custom ControllerFactory:
public class CompositionRoot : DefaultControllerFactory {
protected override IController GetControllerInstance(
RequestContext requestContext, Type controllerType) {
if (controllerType == typeof(OrdersController)) {
var connection = new Ajx.Dal.DapperConnection().getConnection();
return new OrdersController(
new OrdersService(
new OrdersRepository(
Disposable(connection))));
}
else if (...) {
// other controller here.
}
else {
return base.GetControllerInstance(requestContext, controllerType);
}
}
public static void CleanUpRequest() }
var items = (List<IDisposable>)HttpContext.Current.Items["resources"];
if (items != null) items.ForEach(item => item.Dispose());
}
private static T Disposable<T>(T instance)
where T : IDisposable {
var items = (List<IDisposable>)HttpContext.Current.Items["resources"];
if (items == null) {
HttpContext.Current.Items["resources"] =
items = new List<IDisposable>();
}
items.Add(instance);
return instance;
}
}
You can hook your custom controller factory in the Global asax of your MVC application like this:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(
new CompositionRoot());
}
protected void Application_EndRequest(object sender, EventArgs e)
{
CompositionRoot.CleanUpRequest();
}
}
Of course, this all becomes much easier when you use a Dependency Injection framework. For instance, when you use Simple Injector (I'm the lead dev for Simple Injector), you can replace all of this with the following few lines of code:
using SimpleInjector;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var container = new Container();
container.RegisterPerWebRequest<IDbConnection>(() =>
new Ajx.Dal.DapperConnection().getConnection());
container.Register<IOrdersRepository, OrdersRepository>();
container.Register<IOrdersService, OrdersService>();
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
}
There are a few interesting things going on in the code above. First of all, the calls to Register tell Simple Injector that they need to return a certain implementation should be created when the given abstraction is requested. Next, Simple Injector allows registering types with the Web Request Lifestyle, which makes sure that the given instance is disposed when the web request ends (just as we did in the Application_EndRequest). By calling RegisterMvcControllers, Simple Injector will batch-register all Controllers for you. By supplying MVC with the SimpleInjectorDependencyResolver we allow MVC to route the creation of controllers to Simple Injector (just as we did with the controller factory).
Although this code might be a bit harder to understand at first, the use of a Dependency Injection container becomes really valuable when your application starts to grow. A DI container will help you keeping your Composition Root maintainable.
Well, if you're really paranoid about that you can use the finalizer (destructor) to automatically execute the Dispose when the object is being garbage collected. Check this link which explains basically all you need to know about IDisposable, skip to the Examples section if just want a quick sample how to do that. The finalizer(destructor) is the ~MyResource() method.
But any way, you should always encourage the consumers of your libraries to use correctly the Dispose. The automatic cleaning up, by means of garbage collector still presents flaws. You don't know when the garbage collector will do its job, so if you get lots of these classes instantiated and used, then forgotten, in a short time, you may still be in trouble.

Should I implement IDisposable on a singleton?

I have a windows service, which contains a singleton which in turn uses some loggers, message queue listeners and so on. Those classes implements IDisposable. Should I implement IDisposable in singleton itself or do something else to ensure that after service stop/crashing everything will be okay with native resources?
The singleton is implemented like this:
public class Temp
{
private static readonly Lazy<Temp> instance = new Lazy<Temp>(() => new Temp());
private Temp()
{
// create IDisposable objects which use native resources
}
public static Temp Instance
{
get
{
return instance.Value;
}
}
}
I'd rather not implement IDisposable on singleton: IDisposable provokes developer to Dispose the (single) instance:
using(var temp = Temp.Instance) {
...
}
which leads to (possible) crash in some other part of the application (since the single Temp instance has been disposed):
Temp.Instance.SomeFucntion(); // <- possible fail, since Temp.Instanceis disposed
In some rare case if you have to release some resouces aquired, I'd use ProcessExit
event
public class Temp {
private static readonly Lazy<Temp> instance = new Lazy<Temp>(() => new Temp());
private void OnProcessExit(Object sender, EventArgs e) {
// Release native resource if required:
// some resources e.g. files will be closed automatically,
// but some e.g. transactions should be closed (commit/rollback) manually
try {
...
}
finally {
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;
}
}
private Temp() {
// create IDisposable objects which use native resources
// If you have to release some resouces on exit
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
}
public static Temp Instance {
get {
return instance.Value;
}
}
}
No; Singleton shouldn't implement IDisposable. What if someone disposes the instance prematurely when others are in need of that?
Also note that implementing IDisposable will not help you when your service is crashed/stopped. You'll have to dispose it manually! but you can't find right time to do it.
If a type will be returned from a factory that will sometimes need to be cleaned up when the caller is done with them, the type should implement IDisposable. If a particular factory returns a shared singleton object that doesn't actually need any resources, the object returned by the factory should have a Dispose method which silently does nothing. If the factory needs to provide access to a shared singleton resources (e.g. an immutable bitmap stored in a GDI object), it should return a wrapper which will notify the factory when it its Dispose method is called; the factory can then maintain a reference count of wrapper objects and clean up the resource once it knows that no more wrappers will be created and all existing wrappers have been disposed.

Should my component which has an IDisposable constructor dependency be IDisposable?

Here's my class:
public class TaskLogger : ITaskLogger
{
private readonly IDbConnection _dbConnection;
public TaskLogger(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public void LogTask(int clientId, string taskName)
{
_dbConnection.Execute("insert blah",{clientId,taskName}});
}
}
We use Windsor for DI.
Should TaskLogger be declared IDisposable, and dispose the IDbConnection?
No. Since the instance is passed to your class from the caller, the caller is responsible for disposing it. This is because your class should not assume it is the only consumer of this instance - there might be another class that uses the same connection but lives longer than your TaskLogger instance.
Your class should dispose the instances it creates itself.
Another approach would be to add a constructor public TaskLogger(IDbConnection dbConnection, bool closeConnection) and dispose the connection when the value passed in is true. This approach is used by some System.IO classes (although they do it the other way around and use leaveOpen - but for streams it is a different story because usually a stream will not be used by multiple instances at the same time).

How do I retrieve objects in Ninject kernel parameters that need in constructor for initialization

I'm using as Ninject IoC.
My question is how to retrieve an object that requires a parameter in the constructor.
Below a sample code:
//Interface for connection
public interface IConnection
{
IDbConnection CurrentConnection { get; }
}
//Concret connection
public class MyConnection : IConnection
{
public MyConnection(IDbConnection nativeConnection){ }
}
//Module ninject
class Module : NinjectModule
{
public override void Load()
{
Bind<IConnection>().To<MyConnection>().InSingletonScope();
}
}
//Native connection
var sqlConn = new SqlCeConnection();
//Ninject kernel
var ker = new StandardKernel(new Module());
return ker.Get<IConnection>(); //How can I pass as parameters to the constructor of class "MyConnection"??
You have to add/define a binding for IDbConnection. Then Ninject will pass that automatically to the constructor.
For example
Bind<IDbConnection>.To<SqlCeConnection>();
Or you can have a constant in your module
private static readonly SqlConnection = new SqlCeConnection();
And then bind the interface to that
Bind<IDbConnection>.ToConstant(SqlConnection);
Best check this page for more information.
Update
I don't think it's a very sophisticated design. But if you want you can directly pass a parameter to the constructor.
ker.Get<IConnection>(new ConstructorArgument("nativeConnection",yourConnection));
I don't know why exactly you need that, and how it works in singleton scope though.

Categories

Resources