【问题标题】:How to Switch Dynamically between XML and SQL Repository in Web Service/ Web API?如何在 Web 服务/Web API 中的 XML 和 SQL 存储库之间动态切换?
【发布时间】:2014-08-07 22:51:03
【问题描述】:

我有 Web Service 来进行 CRUD 操作。我有由 XMLProductRepository 和 SQLProductRepository 实现的 IProductRepository 接口。

现在我使用 Web 服务控制器中的存储库实例来调用分别在 XMLRepository 和 SQLRepository 中定义的 Get/Put/POST 和 Delete 操作。但是我对如何在这两个存储库之间动态更改有点困惑,因为我想让我的 Web 服务数据库不可知

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 都不应更改。”

【问题讨论】:

  • 花点时间阅读帮助中心的editing help。 Stack Overflow 上的格式设置与其他站点不同。您的帖子看起来越好,用户就越容易为您提供帮助。
  • 只有当你知道你想要什么类型时,你才会实例化存储库。
  • 我会记住您的建议。谢谢!!

标签: c# web-services asp.net-web-api repository-pattern


【解决方案1】:

进入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 中更改实现,而无需更改任何代码。

【讨论】:

  • 很酷,如果有任何问题,请告诉我,可以提供帮助
  • Unity 只是一个例子。对类似框架的 DI(依赖注入)和 IoC(控制反转)进行一些研究,然后选择你最喜欢的。
  • 是的,我确实探索了实现 IOC 的各种方法,我认为 Unity Resolver 是一个很好的解决方案。我也在 asp.net 网站 (asp.net/web-api/overview/extensibility/…) [link]_italic_**bold 上遇到了同样的实现
  • 我尝试使用 UnityDependencyResolver,但如果我使用@Avneesh 提到的代码,我会遇到异常。我被要求用类似 GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container) 来更改我的代码
【解决方案2】:

如果您可以根据提交的 HTTP 动词区分要使用的存储库,则可以根据该动词配置您的路由。更多详情请见this question

【讨论】:

  • 那么我想了解我的 WEB API 请求将设置标准吗?我应该期望曾经使用 API 的客户应该定义吗?如果我们想让它从客户端抽象出来怎么办 - 客户端只关心请求,它不应该知道下面的内容,不是吗?
  • 那么更大的问题(我在您的原始帖子中没有完全看到答案)是使用 XML 和 SQL 存储库之间的定义条件是什么?
猜你喜欢
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多