1

Lets say I have a simple code like this (fiddleLink):

using System;

public class Program
{
    public static void Main()
    {
        //Dependency register logic here
        var service = new DataServiceAdapter();
        var client = new Client(service);
        Foo(client);
    }

    //Work class
    public static void Foo(Client client)
    {
        client.ClientMethod();
    }
}

public class Client
{
    private readonly IDataService _service;
    public Client(IDataService service)
    {
        _service = service;
    }

    public void ClientMethod()
    {
        Console.WriteLine(_service.Method());
        Console.WriteLine(_service.Method2("Hello"));
    }
}

internal class DataServiceAdapter : IDataService
{
    public bool Method()
    {
        using (var something = new SpecifiDataService())
        {
            return something.Method();
        }
    }

    public int Method2(string arg)
    {
        using (var something = new SpecifiDataService())
        {
            return something.Method2(arg);
        }
    }
}

public class SpecifiDataService : IDataService, IDisposable
{
    public bool Method()
    {
        return true;
    }

    public int Method2(string arg)
    {
        return arg.Length;
    }

    public void Dispose()
    {
        //Dispose logic here
    }
}

public interface IDataService
{
    bool Method();
    int Method2(string arg);
}

Goal I want to achieve is to encapsulate using logic from client somewhere else (specifically in DataServiceAdapter class).

Is there any way to write using statement only once and not repeat it in every single method?

P.S. SpecifiDataService may be WCF client service or DbContext of EntityFramework. Both should have short lifespans so I cant just open connection once and work with it.

P.P.S I can't reuse SpecificDataService because in real case it will be WCF proxy-client or EntityFramework DbContext implementation. Both cases contains dozens of method calls, so I have to write using statements everywhere. First of all I want to free my client class from implementation of service. It should work both with short living services and long living ones. Another thing I tried to achieve - write methods without using because its boring copy-paste in every single method

  • Can you briefly describe the kind of cleanup action that will be performed by the Dispose method? If it is third-party code, please try your best to describe what it might do, according to your understanding. The purpose is to evaluate the tradeoffs of deferring the dispose, i.e. to keep the IDataService objects alive for a longer time, possibly across multiple function calls. – rwong Aug 7 '15 at 8:47
  • @rwong SpecifiDataService may be WCF client service or DbContext of EntityFramework. Both should have short lifespans so I cant just open connection once and work with it. – Szer Aug 7 '15 at 9:24
4

C#3+:

internal class DataServiceAdapter : IDataService
{
    public bool Method()
    {
        return Using(s => s.Method());
    }

    public int Method2(string arg)
    {
        return Using(s => s.Method2(arg));
    }

    private static TRes Using<TRes>(Func<SpecifiDataService, TRes> func)
    {
        using (var something = new SpecifiDataService())
        {
            return func(something);
        }
    }
}

C#6:

internal class DataServiceAdapter : IDataService
{
    public bool Method() => Using(s => s.Method());

    public int Method2(string arg) => Using(s => s.Method2(arg));

    private static TRes Using<TRes>(Func<SpecifiDataService, TRes> func)
    {
        using (var something = new SpecifiDataService())
            return func(something);
    }
}

Explanation: extract a command-pattern-like function and then reduce its arity via partial application.

http://codeblog.jonskeet.uk/2012/01/30/currying-vs-partial-function-application

https://stackoverflow.com/questions/327955/does-functional-programming-replace-gof-design-patterns

  • It would be a bunch of one-liners with C#6 by the way. – Den Aug 7 '15 at 9:43
  • Could you show me please how it could be an one-liner in C#6? – Szer Aug 7 '15 at 9:51
  • @Szer ok, done. – Den Aug 7 '15 at 10:07
  • 1
    @gnat the question belongs to codereview.stackexchange.com anyway and they allow code-only answers AFAIK. But I have made an effort to explain. – Den Aug 7 '15 at 12:58
  • 1
    How is this writing using only once? – JeffO Aug 7 '15 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.