使用Entity和Ninject的IOperationInvoker的WCF

时间:2015-03-16 22:33:01

标签: entity-framework wcf ninject wcf-extensions

我有一个WCF服务,我需要将调用记录到其方法中。为此,我使用this解决方案来跟踪调用并调用我的内部审计服务,该服务使用实体5.1并使用Ninject注入服务/存储库/ 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();

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

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

它声称DbContext已被处置错误。

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

我必须提到我在主要网站上的所有这些声明都是相同的,我在MVC4中使用这个后端并且它完美地工作(没有WCF)。因此,我非常确定需要针对WCF生命周期进行纠正,但不确定是什么。

2 个答案:

答案 0 :(得分:1)

我找到了为什么这样做非常讨厌的原因:在由IOperationInvoker,IOperationBehavior和IServiceBehavior组成的链中,我通过前两个的构造函数注入AuditService,但是在最新的(IServiceBehavior)中,因为我用它来装饰WCF类并且不能重载构造函数,所以我使用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永远不会被释放。

答案 1 :(得分:0)

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

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