5
\$\begingroup\$

I wanted to eliminate some duplication and came up with something I've not seen so I figured I post it and see if others had.

Using a delegate to allow the method to return another call to itself.

The commented out code is what I replaced.

delegate ChainRepositoryCommand ChainRepositoryCommand(Action<Data.Repository> action);
ChainRepositoryCommand RepositoryCommand(Action<Data.Repository> action)
{
    using (var repo = new Data.Repository(true))
    {
        action(repo);
    }
    return new ChainRepositoryCommand(a => RepositoryCommand(a));
}

public void Register(ISender<T> sender)
{
    RepositoryCommand
        (repo => repo.AddClient(sender.Name, true))
        (repo => repo.AddMessageType<T>())
        (repo => repo.AddRegistration<T>(this.name, sender.Name));
    //using (var repo = new Data.Repository(true))
    //{
    //    repo.AddClient(sender.Name, true);
    //}
    //using (var repo = new Data.Repository(true))
    //{
    //    repo.AddMessageType<T>();
    //}
    //using (var repo = new Data.Repository(true))
    //{
    //    repo.AddRegistration<T>(this.name, sender.Name);
    //}
    sender.Sending += sender_Sending;
}

Update: I worked it into my repository class as a static method. I know this is all probably obfuscating from a clean code standpoint, but it's fun to experiment with new things from time to time.

public class Repository : IDisposable
{
    ...
    public delegate Chain Chain(Action<Repository> action);
    public static Chain Command(Action<Repository> action)
    {
        using (var repo = new Data.Repository(true))
        {
            action(repo);
        }
        return new Chain(next => Command(next));
    }
    ...
}

public class Server<T> : IServer<T>
{
    ...
    public Server(string name)
    {
        serverName = name;
        Data.Repository.Command
            (repo => repo.AddServer(name));
    }

    public void Register(ISender<T> sender)
    {
        Data.Repository.Command
            (repo => repo.AddClient(sender.Name, true))
            (repo => repo.AddMessageType<T>())
            (repo => repo.AddRegistration<T>(this.serverName, sender.Name));
        sender.Sending += sender_Sending;
    }
    ...
}
\$\endgroup\$
  • \$\begingroup\$ That... Is rather interesting. And a little disturbing. \$\endgroup\$ – Bobson Jul 8 '13 at 20:10
  • \$\begingroup\$ Your business logic and data access is intermingled, which defeats the purpose of repository pattern. \$\endgroup\$ – abuzittin gillifirca Jul 10 '13 at 6:56
  • \$\begingroup\$ to which business logic are you referring? I admit I tend to think of a Repository as a general purpose wrapper around a data context... \$\endgroup\$ – Aaron Anodide Jul 10 '13 at 23:46
2
\$\begingroup\$

Using a delegate to allow the method to return another call to itself.

You don't necessarily need a delegate to allow another call to itself. For example:

public class SimpleCalculation
{
    private int result;

    public int Result
    {
        get { return result; }
    }

    public SimpleCalculation Add(int i)
    {
        result += i;
        return this;
    }

    public SimpleCalculation Subtract(int i)
    {
        result -= i;
        return this;
    }
}

//Usage:
var sc = new SimpleCalculation();
sc.Add(5).Subtract(2);
Console.WriteLine(sc.Result); //Writes '3' to the screen

I'm not saying your code is wrong, only saying that you don't need delegates to achieve this. Also this:

//using (var repo = new Data.Repository(true))
//{
//    repo.AddClient(sender.Name, true);
//}
//using (var repo = new Data.Repository(true))
//{
//    repo.AddMessageType<T>();
//}
//using (var repo = new Data.Repository(true))
//{
//    repo.AddRegistration<T>(this.name, sender.Name);
//}

Could also be rewritten as:

using (var repo = new Data.Repository(true))
{
    repo.AddClient(sender.Name, true);
    repo.AddMessageType<T>();
    repo.AddRegistration<T>(this.name, sender.Name);
}

I don't know if you already knew or tried this but I'm just pointing it out as a possibility. But I agree with you: experimenting with code is fun! :)

| improve this answer | |
\$\endgroup\$

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.