对象和web服务依赖项

本文关键字:依赖 服务 web 对象 | 更新日期: 2023-09-27 18:17:07

我有一个关于实现依赖注入模式的问题。我有一个需要访问web服务的类。根据这种模式,我不应该让我的类实例化服务,因为这会导致对它的强烈依赖。这导致我创建了一个工厂类来构造我的类,并在它的构造函数中传递它所需的正确服务,即依赖项。

对我来说麻烦的是,我正在将web服务客户端的实例传递给我的对象,但这不会使服务打开吗?

我应该传递整个客户端而不是只传递接口吗?这样我就可以实现IDisposable并关闭与服务的连接。

提前感谢。请随意纠正任何术语,不要故意造成混淆。

例如:

public class ProductService
{
    private IProductService client;
    public ProductService(IProductService client)
    {
        this.client = client;
    }
    public void DoIt()
    {
        client.MyWebMethod();
    }
}
public class Factory
{
    public static T Create<T>() where T : class
    {
        T item = null;
        if (typeof(T) == typeof(ProductService))
        {
            item = new CustomerService(**new ProducttServiceClient()**) as T;
        }
        return item;
    }
}

对象和web服务依赖项

是的,如果您自己通过new ProducttServiceClient()创建实例,那么您/factory需要处理它。这就是像Unity, Castle Windsor这样的DI容器可以帮助你释放/处理它的地方。

假设我们正在讨论生成的服务客户端ProducttServiceClient - ClientBase的子类,请注意,如果您处置客户端,它将尝试关闭打开的而不是中止的通道-这可能导致异常。详情请参阅此链接

如果您只是传入打开的通道(System.ServiceModel.ClientBase.CreateChannel()),那么您可以关闭/中止它并再次重用客户端

是的,如果你的工厂类创建了服务客户端实例,它也应该负责关闭它。但是您想要实现什么(除了尝试依赖注入和工厂模式)?在这种情况下,我认为工厂模式给不了你多少好处。

如果你不希望你的客户端创建和关闭代理每次你想调用一个服务操作,我建议在iccommunicationobject上创建一个扩展方法,负责做这项工作,然后关闭代理。然后,您只需要实现处理客户端的逻辑一次(并且在一个地方!)。

扩展名可能像这样:

public static TResult Using<T, TResult>(this T client, Func<T, TResult> work) where T : ICommunicationObject
{
    TResult res = default(TResult);
    try
    {
        res = work(client);
        client.Close();
    }
    catch (CommunicationException)
    {
        client.Abort();
            throw;
    } // ... more catch cases might go here... 
    finally
    {
        if (client.State != CommunicationState.Closed)
            client.Abort();
    }
    return res;
}

您的客户端将像这样调用方法:

using TheNameOfYourNamespaceDefiningTheExtension
return new ServiceClient().Using(client => client.MethodName(request));