是否有在Web应用程序中访问业务逻辑服务的最佳实践?

时间:2008-12-18 00:49:07

标签: c# .net architecture web-applications

在Web应用程序中实例化/调用业务逻辑层服务是否有最佳实践?我有大量的服务,我一直在实例化,然后只处理一个方法调用。

这些应该作为提供者实施吗?或者可以从单身人士访问?

示例代码:

void ShipProduct(){
  ProductService service = new ProductService();
  service.Ship(aProduct);
}

显然它比这复杂得多,我只是不知道我是否通过在任何地方创建这些服务的新实例来做错事。

4 个答案:

答案 0 :(得分:3)

我会对单身人士保持警惕。它经常被滥用在并不总是需要它的地方。如果一次只应该有一个该类的实例,则应该只使用单例。在此示例中,仅当您希望一次执行一个Ship()操作时,才使用单例。

我喜欢使用的一种模式是为类中的服务创建一个私有只读字段,可能如下所示:

public ShippingController
{
    private readonly ProductService productService;

    public ShippingController(ProductService service)
    {
         productService = service;
    }        

    void ShipProduct(Product aProduct)   
    {
        service.Ship(aProduct);
    }
}

至少这样,你不受任何决定的束缚,你可以创建一个在你的应用程序中使用的全局ProductService,或者你可以创建一个新的实例并将其传入,这样你就可以拥有最好的这两个世界。

至于哪种方式更好,这取决于你的情况。仔细考虑使用您的服务的具体要求是什么,并相应地实施。

答案 1 :(得分:3)

我总是觉得最好在应用程序层之间进行松散耦合,因此我建议您在服务客户端代码(ProductService)和调用它的代码之间引入一些抽象级别。

在很多情况下(我不确定这是否是您的情况),任何特定团队都可以以类似产品的方式访问应用程序的任何其他层。换句话说,另一个团队可能拥有业务层,并可能在您的层代码中引入重大更改。

我建议您创建一个服务客户端工厂,用于实例化客户端对象并从工厂返回仅显示您选择的成员的自定义接口类型。这不仅可以为您提供松散耦合,还可以灵活地在中心位置配置和调整客户端对象。

足够的话,这里有一些代码:

using System;

// this is your interface that will create the 
// loose coupling that you want
interface IProduct { void Ship(); }

// make sure you generate your proxy code with
// partial classes so you can then create your 
// own parial class to implement the interface
partial class ProductService : IProduct
{
    public void Ship()
    {
        // in here you would do validation
        // and other things and then call the
        // real ship method on the client
    }
}

static class Factory
{
    public static IProduct GetProduct()
    {
        // configure away...do 
        // whatever you need to do...

        return new ProductService() as IProduct;
    }
}

答案 2 :(得分:2)

我实际上已经做到了。这取决于你想要达到的目标。如果您正在尝试增加代码的简洁性,那么您尝试调用的服务的单例/静态引用会有所帮助。

Services.ProductService.Ship(aProduct)

然而,你必须记住,你放入一个不是自然单身的单身人士的任何东西都会造成人为的瓶颈。如果您的服务的构建/处置不是资源密集型的(如果它只包含业务逻辑则不会),我会继续做您正在做的事情。

此外,创建一个您根本不需要的架构会使代码更难以遵循。这都是判断力。

希望有所帮助!

答案 3 :(得分:2)

对于一个简单的Web应用程序我会问,我会问这个问题:调用之间是否有任何给定服务有状态(包括连接对象到db等)?

  • 是)每次通话实例化
  • 否)使用Singleton服务

如果服务在调用之间保持状态,那么它绝对不是线程安全的。如果它没有在两次通话之间保持任何状态,那么它就是。最终你必须考虑线程安全。单个服务是否可以与许多客户一起调用它?

无论你实现它,我都会使用工厂模式来实现一定程度的多态性,并将服务的实例化与实现分开。考虑以下psuedo-C#-code:

public static class ServiceFactory
{
  public static T GetService<T>()
  {
    //either instantiate a new service 
    //or retrieve singleton service here base on type T
  }
}

这使您可以在一个地方更改任何有状态或单身服务的服务。