使用WCF服务在C#服务器中使用穷人的DI

时间:2015-12-01 19:03:03

标签: c# .net wcf dependency-injection inversion-of-control

我在C#和WCF中构建服务器。我的服务合同包含客户端应用使用的方法。但整个逻辑在不同的类别中分开: BusinessLogic 。我将在BussinessLogic中注入我需要的所有内容,例如存储库/数据库提供程序或存储在内存中的其他数据。我使用穷人的依赖来构建我的BussinessLogic(它是我的作品根)。它是一个控制台应用程序,因此BussinessLogic以Main(string[] args)方法创建/解析。

我的问题是WCF服务是使用无参数构造函数创建的,与服务器的其余部分无关。每当用作客户端时,它们就会被创建。

这就是我的服务器的样子:

    static void Main(string[] args)
    {
        ServiceHost host = new ServiceHost(typeof(ServiceLayer), new Uri("net.tcp://localhost:8005"));
        host.Open();

        Console.WriteLine("Running... Press key to stop");
        Console.ReadKey();
    }

我的服务:

[ServiceContract]
public interface IServiceContract
{
    [OperationContract]
    ...
}

public class ServiceLayer : IServiceContract
{
    IBusinessLogic _businessLogic;
    public ServiceLayer(IBusinessLogic businessLogic)
    {
        _businessLogic = businessLogic;
    }

    // Here, I would like to use IBusinessLogic
    ...
}

我找到了如何使用IoC here(我没有对它进行测试),但我正在寻找一个最好的解决方案穷人的依赖,没有任何容器或工具,只有C#和.NET。如果没有任何解决方案与IoC一样好或接近它,请发表评论。

2 个答案:

答案 0 :(得分:4)

如果您围绕commandsqueries对应用程序进行建模,则可以非常轻松地将您的WCF服务创建为thin maintenance free layer with just one service class

如果只有一个服务类,则可以将此服务类本身用作Composition RootHumble Object,这意味着您无需将任何依赖项注入服务类。这可以防止您在依赖注入方面完成任何与WCF管道的集成!

应用这些模式时,您可以将服务减少到以下代码:

[ServiceKnownType(nameof(GetKnownTypes)]
public class CommandService
{
    [OperationContract, FaultContract(typeof(ValidationError))]
    public void Execute(dynamic command) {
        CreateCommandHandler(command.GetType()).Handle(command);
    }

    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider cap) {
        yield return typeof(ShipOrder);
        yield return typeof(CancelOrder);
        yield return typeof(ConfirmOrder);
    }

    // Singletons
    private static IUserContext userContext = new WcfUserContext();

    private static dynamic CreateCommandHandler(Type commandType)
    {
        var context = new DbContext();

        if (commandType == typeof(ShipOrder))
            return Decorate(new ShipOrderHandler(context));
        if (commandType == typeof(CancelOrder))
            return Decorate(new CancelOrderHandler(context));
        if (commandType == typeof(ConfirmOrder))
            return Decorate(new ConfirmOrderHandler(context, userContext));

        throw new ArgumentException("Unknown: " + commandType.FullName);
    }

    private static ICommandHandler<T> Decorate<T>(ICommandHandler<T> handler) {
        return new WcfExceptionTranslatorCommandHandlerDecorator(
            new LoggingCommandHandlerDecorator(
                new Logger(),
                new AuditTrailingCommandHandlerDecorator(
                    new PermissionCheckerCommandHandlerDecorator(
                        new ValidationCommandHandlerDecorator(
                            new TransactionCommandHandlerDecorator(
                                handler))))));
    }
}

答案 1 :(得分:3)

穷人的DI现在被称为Pure DI

您可以使用Pure DI来构建WCF应用程序。您需要在Composition Root

中执行此操作

在WCF应用程序中,Composition Root是一个自定义的ServiceHostFactory。

This answer显示了如何执行此操作的示例。

您可以自定义该答案中的代码以添加更多依赖项。