1

I have Web Service to carry CRUD operation. I have IProductRepository interface implemented by XMLProductRepository and SQLProductRepository.

Now i use the repository instance in my controller of the web service to invoke Get/Put/POST and Delete operations which are defined respectively in XMLRepository and SQLRepository. But i am getting little confused as how to change dynamically between these two repositories as i want to make my web service database agnostic

public interface IProductRepository
{
    IEnumerable<Product> GetAll();
    Product Get(int id);
    Product Add(Product item);
    void Remove(int id);
    bool Update(Product item);
}

public class XMLProductRepository : IProductRepository
{

    public XMLProductRepository() {}
    public IEnumerable<Product> GetAll() {}
    public Product Get(int id) {}
    public Product Add(Product item) {}
    public void Remove(int id) {}
    public bool Update(Product item) {}
}

public class SQLProductRepository : IProductRepository
{
    public SQLProductRepository() {}
    public IEnumerable<Product> GetAll() {}
    public Product Get(int id) {}
    public Product Add(Product item) {}
    public void Remove(int id) {}
    public bool Update(Product item) {}
}   

public class ProductController : ApiController
{

   static readonly IProductRepository repository = new XMLProductRepository();

   // REST OF THE CODE AND IMPLEMENTATION HERE...
   // using the repository object

}        

The question is how do i make it dynamic here, instead of defining the specific repository object in controller? Or the question is, can i even do that for this WEB API?

Let me add further details to the Question - Thanks to Dillie-O for pointing it out.

The requirement i have got is "Sources are mutually exclusive. At any point of time, service picks information from only one source either XML or SQL. The Service should be able to switch between sources without client knowledge. In addition to that Service WEB API shouldn't change whenever my source changes."

vran
  • 163
  • 3
  • 11
  • Take a moment to read through the [editing help](http://stackoverflow.com/editing-help) in the help center. Formatting on Stack Overflow is different than other sites. The better your post looks, the easier it will be for users to help you. – gunr2171 Jun 17 '14 at 19:43
  • You would only instantiate the repository when you know what type you want. – Neil Smith Jun 17 '14 at 19:53
  • I will keep your suggestions in mind. Thanks!! – vran Jun 17 '14 at 20:23

2 Answers2

1

Go to the mvc project and add nuget package Unity.Mvc3 or mvc4 based on your project. This will bring a class called Bootstrapper.cs in the project. Add your type here as shown:

 public static class Bootstrapper
{
    public static void Initialise()
    {
        var container = BuildUnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
        //Register the repository
        container.RegisterType<IProductRepository, SQLProductRepository>();
        return container;
    }
}

In the global.config called the bootstrapper.initialise():

protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();
        Bootstrapper.Initialise();

    }

You can now set up controllers like this:

 public class HomeController : Controller
{
    private readonly IProductRepository productRepository;

    public HomeController(IProductRepository productRepository)
    {
        this.productRepository = productRepository;
    }

and the correct type will be sent. You can change the implementation any time in bootstrapper.cs without changing any code.

Avneesh
  • 654
  • 4
  • 6
  • Cool, Let me know if any issues and can help – Avneesh Jun 17 '14 at 21:18
  • Unity is just one example. Do some research on DI (Dependency Injection) and IoC (Inversion of Control) for similar frameworks and choose your favourite. – djikay Jun 17 '14 at 21:30
  • Yes, i did explored various ways to achieve IOC and i think Unity Resolver is good solution. I also came across on same sort of implementation at asp.net website (http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver) [link]_italic_**bold – vran Jun 18 '14 at 00:08
  • I tried using the UnityDependencyResolver, but if i use the code as mentioned by @Avneesh i got Exception. I was required to change my code with something like, GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container) – vran Jun 18 '14 at 00:34
0

If you can distinguish which repository is to be used based on the HTTP verb being submitted, you can configure your routes based on that. More details about that can be found in this question.

Community
  • 1
  • 1
Dillie-O
  • 29,277
  • 14
  • 101
  • 140
  • So am i suppose to understand that my WEB API request will set the criteria? Should i expect the client who ever is using the API should define? What if we want to keep it abstract from the client what goes under - Client is just concerned with request, it shouldn't know the under goings, isn't it? – vran Jun 17 '14 at 20:26
  • The bigger question then (which I didn't quite see an answer to in your original post) is what is the defining condition between using the XML and the SQL repositories? – Dillie-O Jun 17 '14 at 20:38