Как да превключвате динамично между XML и SQL хранилище в уеб услуга/уеб API?

Имам уеб услуга за извършване на CRUD операция. Имам интерфейс на IProductRepository, внедрен от XMLProductRepository и SQLProductRepository.

Сега използвам екземпляра на хранилището в моя контролер на уеб услугата, за да извикам операции Get/Put/POST и Delete, които са дефинирани съответно в XMLRepository и SQLRepository. Но малко се обърквам как да променям динамично между тези две хранилища, тъй като искам да направя моята база данни на уеб услуга агностична

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

}        

Въпросът е как да го направя динамичен тук, вместо да дефинирам конкретния обект на хранилище в контролера? Или въпросът е мога ли дори да направя това за този WEB API?

Позволете ми да добавя допълнителни подробности към Въпроса - Благодаря на Dillie-O, че го посочи.

Изискването, което имам, е „Източниците са взаимно изключващи се. Във всеки един момент услугата избира информация само от един източник или XML, или SQL. Услугата трябва да може да превключва между източници без знание на клиента. В допълнение към този WEB API на услугата не трябва да се променя винаги, когато източникът ми се промени."


person vran    schedule 17.06.2014    source източник
comment
Отделете малко време, за да прочетете помощта за редактиране в помощния център. Форматирането в Stack Overflow е различно от другите сайтове. Колкото по-добре изглежда вашата публикация, толкова по-лесно ще бъде за потребителите да ви помогнат.   -  person gunr2171    schedule 17.06.2014
comment
Бихте инстанцирали хранилището само когато знаете какъв тип искате.   -  person Neil Smith    schedule 17.06.2014
comment
Ще имам предвид вашите предложения. Благодаря!!   -  person vran    schedule 18.06.2014


Отговори (2)


Отидете до проекта mvc и добавете nuget пакет Unity.Mvc3 или mvc4 въз основа на вашия проект. Това ще доведе до клас, наречен Bootstrapper.cs в проекта. Добавете вашия тип тук, както е показано:

 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;
    }
}

В global.config, наречен 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();

    }

Вече можете да настроите контролери по следния начин:

 public class HomeController : Controller
{
    private readonly IProductRepository productRepository;

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

и правилният тип ще бъде изпратен. Можете да промените внедряването по всяко време в bootstrapper.cs, без да променяте никакъв код.

person Avneesh    schedule 17.06.2014
comment
Страхотно, уведомете ме, ако имате проблеми и можете да помогнете - person Avneesh; 18.06.2014
comment
Единството е само един пример. Направете проучване относно DI (инжектиране на зависимост) и IoC (инверсия на контрол) за подобни рамки и изберете любимата си. - person djikay; 18.06.2014
comment
Да, проучих различни начини за постигане на IOC и мисля, че Unity Resolver е добро решение. Също така попаднах на същия вид внедряване на уебсайта на asp.net (asp.net/web-api/overview/extensibility/) [връзка]_italic_**удебелен - person vran; 18.06.2014
comment
Опитах да използвам UnityDependencyResolver, но ако използвам кода, споменат от @Avneesh, получих изключение. Трябваше да променя кода си с нещо като GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(контейнер) - person vran; 18.06.2014

Ако можете да различите кое хранилище да се използва въз основа на подадения HTTP глагол, можете да конфигурирате вашите маршрути въз основа на това. Повече подробности за това можете да намерите в този въпрос.

person Dillie-O    schedule 17.06.2014
comment
И така, трябва ли да разбирам, че моята WEB API заявка ще зададе критериите? Трябва ли да очаквам, че клиентът, който някога използва API, трябва да дефинира? Ами ако искаме да запазим абстрахата от клиента какво става - Клиентът просто се интересува от заявка, не трябва да знае какво става, нали? - person vran; 18.06.2014
comment
Тогава по-големият въпрос (на който не видях отговор в оригиналната ви публикация) е какво е определящото условие между използването на XML и SQL хранилищата? - person Dillie-O; 18.06.2014