简体   繁体   中英

Use of context and repository in EF WCF services

I am using Entity Framework code first in my data layer using the repository pattern. I'm currently designing my WCF web services to connect to the data layer and I'm just a little confused about how to link up with the data layer.

In my test project for the data layer I create a new DbContext class for each test, wrap that in a using block, within that I create the repository class, passing in the context as the constructor parameter. I can then call my methods on the repository to get the data back.

Is this correct for a start and then do I do the same in the WCF service methods?

Eg would I have

 public class UserService : IUserService
    {
        public bool CheckEmailAvailability(string email)
        {
            try
            {
                using (var context = new MyDbContext())
                {
                    var repository = new UserDataRepository(context);
                    var emailAvailable =
                        repository.GetItems().Count(
                            u => u.EmailAddress.Equals(email, StringComparison.InvariantCultureIgnoreCase)) == 0;

                    return emailAvailable;
                }
            }
        }
    }

Or am I using the context/repository concept wrong?

It also strikes me that it would be handy to use DI here so I could mock the data context/repository objects in a WCF service test project. Is this something usually done and if so, does anyone have any links to an example or tutorial on this?

First of all, yes it would be better to inject the repository, or (if your chosen DI framework is unable to resolve them) a factory for the repository.

Additionally it might be a good idea to remove the idea of the context from your service. To my mind the repository and it's helpers should deal with the context, and if necessary with sharing the context between various DB calls required to assemble your entities. Then the services can request entities from the repositories without worrying about whether they're being source from a DB or some other data-store.

public class UserService: IUserService
{
    IUserRepository userRepository;

    ... // ctor to inject repository

    public bool CheckEmailAvailability(string email)
    {
        var emailAvailable = !userRepository.GetUserEmails().Any(u => u.EmailAddress.Equals(email, StringComparison.InvariantCultureIgnoreCase));

        return emailAvailable;                            
    }
}

public class UserRepository: IUserRepository
{
    ...

    public IEnumerable GetUserEmails()
    {
        // actually this context should be handled more centrally, included here for sake of illustration
        using (var context = new MyDbContext()) 
        {
            return repository.GetItems();
        }
    }
}

Finally, with regard to WCF services, I'm not certain what the best advice is. I've seen code where WCF services were created in the middle of business logic, which was awful, but a limitation of the oldish WPF code-base and limited DI. The better situations are where a ChannelFactory or service factory can be injected into your service layer. You may find this answer on Dependency Injection wcf helpful.

And as always, if you're planning to TDD your code, I'd definitely recommend wrapping the intersection points between layers of your application in interfaces so that they're easier to mock out. It sounds like you've got the right idea there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM