0

I have a somewhat simple web app, that uses an ASMX web service as its sole data access. All the information is gotten from it, and saved to it. It works fine so thats out of the way.

I just updated to VS2012, and it complained about the class implementing the service reference, does not inherit from IDisposeable.

After some reading, i am more confused as some solutions are really elaborate, some are simple. Short version is, after understanding so little, it seems like i cant adapt it to how my app is made.

I have several data access classes, all focusing on methods for an area. For example, one dataaccess for customer related calls, one for product related calls etc.

But since they are all using the same service, they all derive from a base data access class that holds the reference.

This is the base data access class:

public class BaseDataAccess
{
    private dk.odknet.webudv.WebService1 _service;
    private string _systemBrugerID, _systemPassword;

    public BaseDataAccess()
    {
        //Gets the system user and password that is stored in the webconfig file. This means you only have to change
        //the username and password in one place without having to change the code = its not hardcoded.
        _systemBrugerID = System.Configuration.ConfigurationManager.AppSettings["SystemBrugerID"].ToString();
        _systemPassword = System.Configuration.ConfigurationManager.AppSettings["SystemPassword"].ToString();
        _service = new dk.odknet.webudv.WebService1();
    }

    /// <summary>
    /// Gets an instance of the webservice.
    /// </summary>
    protected dk.odknet.webudv.WebService1 Service
    {
        get { return _service; }
    }

    /// <summary>
    /// Gets the system user id, used for certain methods in the webservice.
    /// </summary>
    protected string SystemBrugerID
    {
        get { return _systemBrugerID; }
    }

    /// <summary>
    /// Gets the system user password, used for certain methods in the webservice.
    /// </summary>
    protected string SystemPassword
    {
        get { return _systemPassword; }
    }
}

And here is how a derived class utilizes the service reference from the base class:

public class CustomerDataAccess : BaseDataAccess
{
    public CustomerDataAccess() {}

    /// <summary>
    /// Get's a single customer by their ID, as the type "Kunde".
    /// </summary>
    /// <param name="userId">The user's username.</param>
    /// <param name="customerId">Customer's "fkKundeNr".</param>
    /// <returns>Returns a single customer based on their ID, as the type "Kunde".</returns>
    public dk.odknet.webudv.Kunde GetCustomerById(string userId, string customerId)
    {
        try
        {
            return Service.GetKunde(SystemBrugerID, SystemPassword, userId, customerId);
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
            throw;
        }
    }}

So how on earth do i implement IDisposable in this situation? I just cant wrap my head around it.

EDIT I have fiddled with the service reference, and come up with this:

/// <summary>
    /// Gets an instance of the webservice.
    /// </summary>
    protected dk.odknet.webudv.WebService1 Service
    {
        get
        {
            try
            {
                using (_service = new dk.odknet.webudv.WebService1())
                {
                    return _service;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                throw;
            }
        }
    }

Yes the exception handling isnt great, i will get to that (advice is appreciated), but VS2012 does not complain about the lack of IDisposable anymore. Instantiation of the service has been removed from the constructor. The app works fine without any further modifications. Will this suffice?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Frederik T
  • 533
  • 2
  • 10
  • 30
  • 1
    I don't have time to look up the reference, but a service reference is one of the very few places where you do _not_ want to use a `using` block. Long story short, the `Dispose` call that happens at the end of the `using` block can actually throw an exception in the case of a WCF proxy class. This will destroy any exception that was thrown within the `using` block. Search the web for "indisposable" – John Saunders Oct 10 '13 at 21:40
  • As far as i understood, you should avoid using a "using" if its a WCF service, but it doesnt matter with an ASMX service. Or did i misunderstand? – Frederik T Oct 10 '13 at 21:43
  • 1
    You misunderstood. It doesn't matter what kind of service it is. If you are using a Service Reference, then you are creating a WCF proxy class, and should not use `using`. With the legacy web references, that didn't matter. – John Saunders Oct 10 '13 at 21:45
  • Ah ok, that makes sense now. Well, what should i do then? – Frederik T Oct 10 '13 at 21:47
  • Search for "indisposable", like I said. One technique is in an old blog post of mine (http://johnwsaunders3.wordpress.com/2009/05/17/how-to-consume-a-web-service/), but there are better ones you'll find if you search. – John Saunders Oct 10 '13 at 21:49
  • I have looked around, found stuff like this: http://thorarin.net/blog/post/2010/05/30/Indisposable-WCF-clients.aspx which is easier to understand, but i dont think it will work when getting a full reference. Oh well, i will keep looking but at least i am a few steps further. – Frederik T Oct 10 '13 at 22:20
  • I don't know what you mean by a "full reference". That code will precisely work! That's the example that _I_ always use! – John Saunders Oct 10 '13 at 22:22
  • Ok i will give it a shot. What i meant is, the examples call a specific method in the service, whereas i just return a reference to the service. Hence the above code. – Frederik T Oct 10 '13 at 22:35
  • Oh, ok. What I generally do is create at least one static class and generic method for calling services. The parameters to that method sometimes become nasty, so I wind up with a non-static class, each instance of which holds the non-varying parameters, and the method then is called with the rest. – John Saunders Oct 10 '13 at 23:01
  • Found links: See . Also, see "[What is the best workaround for the WCF client `using` block issue?](http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue)". – John Saunders Oct 11 '13 at 10:38

0 Answers0