我在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一样好或接近它,请发表评论。
答案 0 :(得分:4)
如果您围绕commands和queries对应用程序进行建模,则可以非常轻松地将您的WCF服务创建为thin maintenance free layer with just one service class。
如果只有一个服务类,则可以将此服务类本身用作Composition Root或Humble 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显示了如何执行此操作的示例。
您可以自定义该答案中的代码以添加更多依赖项。