Animesh D
Animesh D

Reputation: 5002

How to return an enumerable object when using repository pattern?

I am working on a simple WCF application and I am having trouble with properly setting up the Repository pattern. The communication pattern of the application is roughly as shown here.

I am concerned with the part that says Admin Console Mode. In this mode, the admin has access to some admin features like adding users and viewing existing users etc.

Abstract contract of one of the entities, Users, needed for this mode, is as follows:

public interface IUserRepository
{
    byte AddUser(string _loginname, string _loginpass);
    Users ShowAllUsers();
}

The concrete implementation of this repository:

public class UserRepository : IUserRepository
{
    public UserRepository(string connectionString)
    {
        _connectionString = connectionString;
    }

    public byte AddUser(string _loginname, string _loginpass)
    {
        . . .
    }

    public Users ShowAllUsers()
    {
        string query = "select login_name,created_time from users";

        using(SqlConnection conn = new SqlConnection(_connectionString))
        {
            using(SqlCommand cmd = new SqlCommand(query, conn))
            {                    
                conn.Open();

                using(var reader = cmd.ExecuteReader())
                {
                    if(!reader.Read())
                        return null;

                    return new Users
                    {
                        Login_Name = reader.GetString(reader.GetOrdinal("login_name")),
                        Login_Pass = reader.GetString(reader.GetOrdinal("login_pass")),
                        Created_Time = reader.GetDateTime(reader.GetOrdinal("created_time")),
                    };
                }
            }
        }
    }
}

From the Host layer, How do I access the list of Users objects returned from the ShowAllUsers method? I tried this way:

public void ShowUsers()
{
    Users user = _repo.ShowAllUsers();

    Console.WriteLine("Name\tCreated Time");

    foreach(Users u in user)
    {
        Console.WriteLine("{0}\t{1}",u.Login_Name,u.Created_Time);
    }
}

From what I understand, this does not work obviously since the Users object is not an enumerable object. How do I modify the Users entity and the repository contract and the repository implementation so that the Users object is returned to be displayed on the screen?

Users.cs
UserRepository.cs
IUserRepository.cs

Upvotes: 2

Views: 290

Answers (1)

abatishchev
abatishchev

Reputation: 100328

Entity:

// note the singular form, it makes much more sense for me, as far as the object represents a single entity (user)
// also not an interface, optionally
public class User : IUser
{
}

Repository:

public class UserRepository : IUserRepository
{
    public IEnumerable<IUser> ShowAllUsers()
    {
        ...
        while (reader.Read())
        {
             yield return new User
             {
                 ...
             };
        }
    }
}

I recommend yo use interfaces everywhere, because if you will want to switch from ADO.NET query to an ORM, you will need to rewrite much less code.


Usage:

foreach (User u in users)
{
    Console.WriteLine("{0} created on {1}", u.Login, u.CreationTime);
}

Upvotes: 4

Related Questions