Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Interface for Async access

My standard layout for any data access involves a nice simple interface.

    public interface IUserDao
    {
      User GetUser(int userId);
    }

I can then switch in a different implementation of the data layer for unit testing. A standard use would be from a presenter in MVP to do something simple like pushing the data into view.

    public void UserSelected(int userId)
    {
       User user = daoFactory.UserDao.GetUser(userId);

       view.FirstName = user.FirstName;
       view.LastName = user.LastName;
    }

In this instance the data access needs to be completed asynchronously. I can't quite get my head around if the requirement for async call should make its way down as far as the data interface.

e.g.

    public interface IUserDao
    {
      void GetUserBegin(int userId);
      User GetUserEnd();
    }

Do I need to alter the interface or is the requirement of async access just part of the implementation in the calling code?

EDIT :

I thought my simple example would help but it may actually be causing some confusion. I am using RestSharp to obtain the data I need and that nicely handles the async part for me. What I can't work out is how I can wrap an interface around this lot so I can switch it out during testing.

public UserDao : IUserDao
{
    public void GetUser(int userId)
    {           
        var request = new RestRequest("User/GetUser/{id}", Method.POST);

        // replaces matching token in request.Resource
        request.AddUrlSegment("id", id.ToString()); 

        //Create the client
        var client = AuthenticatedRestClient();

        //Execute
        client.ExecuteAsync(request, response =>
        {
            ProcessUser(response);
        });
    }        

    public static void ProcessUser(IRestResponse response)
    {
        //Extract the user from the reponse
        User user = (User)ProcessResponse<User>(response);
    }
}
like image 341
fluent Avatar asked Mar 12 '26 00:03

fluent


2 Answers

If your using the await pattern you can just do

public interface IUserDao
{
  Task<User> GetUser(int userId);
}

and to call it

 User user = await daoFactory.UserDao.GetUser(userId); 

Its nice because it informs your application layer that this method was made to be called asynchronously.

like image 109
pingoo Avatar answered Mar 14 '26 14:03

pingoo


If you are in the latest version of .NET, you can take advantage of async - await:

public interface IUserDao
{
    Task<User> GetUser(int userId);
}

public async Task UserSelected(int userId)
{
   User user = await daoFactory.UserDao.GetUser(userId);

   view.FirstName = user.FirstName;
   view.LastName = user.LastName;
}

Please note that the implementation of GetUser should return Task<User>.

If you are on version .NET 4.0, you can use Task to call UserSelected from upper method:

Task.Factory.StartNew(() => UserSelected(userId));
like image 25
cuongle Avatar answered Mar 14 '26 12:03

cuongle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!