WCF 与 IOperationInvoker 使用实体和 Ninject

WCF with IOperationInvoker using Entity and Ninject

我有一个 WCF 服务,我需要从中记录对其方法的调用。为此,我使用 this 解决方案来跟踪调用并调用我的内部审计服务,该服务使用实体 5.1 并使用 Ninject.

注入 services/repositories/DbContext

我的 Invoke 方法如下所示:

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        var methodParams = (instance).GetType().GetMethod(_operationName).GetParameters();
        var parameters = new Dictionary<string, object>();
        for (var index = 0; index < inputs.Length; index++)
            parameters.Add(methodParams[index].Name, inputs[index]);

        _auditService.TrackFilterParametersValues(_operation.Parent.Type.FullName, _operationName, _operation.Action, parameters);

        return _baseInvoker.Invoke(instance, inputs, out outputs);
    }

在我的 Ninject 模块中,我将内部内容注册如下:

Bind<IAuditService>().To<AuditeService>().InRequestScope();
Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
Bind<DbContext>().To<MyEntities>().InRequestScope();

当我在存储库中调用 dbContext 来添加新的 Audit 对象时出现问题,如下所示:

_dbContext.Set<T>().Add(entity);

声称 DbContext 已被释放是错误的。

在 WCF 服务上注册 DbContext 以便为 IOperationInvoker 注册的正确方法是什么?

我必须提到,对于我在 MVC4 中使用此后端提供的主站点,我的所有声明都是相同的,并且它运行良好(那里没有 WCF)。所以我很确定需要针对 WCF 生命周期进行更正,但不太确定是什么。

如果 MyEntities 继承自 DbContext,那么这应该有效:

Bind(typeof(DbContext)).To(typeof(MyEntities)).InRequestScope();

我找到了为什么这表现如此糟糕的原因:在由 IOperationInvoker、IOperationBehavior 和 IServiceBehavior 形成的链中,我通过其中前两个的构造函数注入了 AuditService,但在最新的(IServiceBehavior ), 因为我用它装饰 WCF class 并且不能重载构造函数,所以我使用 DependencyResolver 来获得 AuditService 与 属性 像这样:

public IAuditService AuditService
{
    get { return DependencyResolver.Current.GetService<IAuditService>();
}

然后,当我开始调试时,我注意到构造函数在 WCF 测试客户端向 WCF 查询 WSDL 数据时被调用,但是 Invoke 方法从未被调用调用是因为没有调用 web 方法。因此,AuditService 实例(和 DbContext)在构造函数的调用期间都很好,但是在调用 web 方法和调用 IOperationInvoker 的 Invoke 方法时,DbContext 早就被释放了。

我的解决方法是从所有构造函数中删除对 AuditService 的所有引用,并将带有 DependencyResolver 的 属性 从 ServiceBehavior 移动到 IOperationInvoker 实现。完成此操作后,AuditService 会在需要时被调用,之前从未被调用过,并且它的 DbContext 也不会被释放。