WCF Integration

157 views
Skip to first unread message

Chris

unread,
Oct 2, 2009, 8:46:31 AM10/2/09
to ninject-dev
Hey All,

I'm currently using the WCF extensions found at
http://github.com/idavis/ninject.extensions.wcf and it seems to be
doing the trick for creating my services nicely etc. What I need now
is the ability to scope objects per service call (for example an
NHibernate session or Linq2Sql data context). What I thought might
work was simple creating an extension to the BindingBuilder<T>
(basically add an InInstanceContextScope method) class which sets
"this".Binding.Scope to ctx=>OperationContext.Current.InstanceContext
but this doesn't seem to work (or at least my call to OnDeactivated
never fires).

Any ideas, I know I've made a few guesses about how binding works here
so any general info would also be appreciated.

Chris Meek


Guido Ziliotti

unread,
Oct 2, 2009, 10:27:20 AM10/2/09
to ninje...@googlegroups.com
I'm interested in wcf scoping too and just started using ninject.extensions.wcf.
At present I am looking around for recepies outlined by some developers, some of
these are presente in previous conversation by Ian.

Currently I am experimenting some difficulties tough. I've just reassembled the example project
but I am definitly missing something because as soon as I use

Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"

in .svc  file I have an exception on service activation

        protected override void OnOpening(){
            Description.Behaviors.Add( new NinjectServiceBehavior() );//Description is null!!!
            base.OnOpening();
        }

Description is null. So I've made something wrong. But I am missing the point.

Any help is welcome.

Then I have another question related to the original WcfTimeService. I Expected to be able to Inject
ISystemClock in the service ctor. I think this should be the all point of wcf uinfrastucture.
But it seems the no argument ctor is necessary.

Chris

unread,
Oct 5, 2009, 4:38:31 AM10/5/09
to ninject-dev
That's interesting Guido, I'm using the same library and have it
working absolutely fine for me (Did you add a global.asax and derive
it from the Application object in the library, that could cause a few
problems if not done I guess).

I'm now at the point where I need to have ninject return objects
scoped to the wcf call (I use percall services you see).

I know Nate mentioned on his blog he was going to write a post
sometime about the new GC based scoping features of 2.0 but was hoping
someone else may have already played with this.

On 2 Oct, 15:27, Guido Ziliotti <guido.zilio...@gmail.com> wrote:
> I'm interested in wcf scoping too and just started using
> ninject.extensions.wcf <http://github.com/idavis/ninject.extensions.wcf>.
> At present I am looking around for recepies outlined by some developers,
> some of
> these are presente in previous conversation by Ian.
>
> Currently I am experimenting some difficulties tough. I've just reassembled
> the example project
> but I am definitly missing something because as soon as I use
>
> Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"
>
> in .svc  file I have an exception on service activation
>
>         protected override void OnOpening(){
>             Description.Behaviors.Add( new NinjectServiceBehavior()
> );//Description is null!!!
>             base.OnOpening();
>         }
>
> Description is null. So I've made something wrong. But I am missing the
> point.
>
> Any help is welcome.
>
> Then I have another question related to the original* WcfTimeService*. I
> Expected to be able to Inject
> ISystemClock in the service ctor. I think this should be the all point of
> wcf uinfrastucture.
> But it seems the no argument ctor is necessary.
>
>
>
> On Fri, Oct 2, 2009 at 2:46 PM, Chris <cmdrk...@googlemail.com> wrote:
>
> > Hey All,
>
> >           I'm currently using the WCF extensions found at
> >http://github.com/idavis/ninject.extensions.wcfand it seems to be

Guido Ziliotti

unread,
Oct 5, 2009, 4:55:06 AM10/5/09
to ninje...@googlegroups.com
I am deriving from your WcfApplication class.

Ian Davis

unread,
Oct 5, 2009, 3:24:35 PM10/5/09
to ninje...@googlegroups.com
Did switching to ctx=>OperationContext.Current resolve your issue?

-Ian
--
Ian Davis
http://disassembla.net

Chris

unread,
Oct 6, 2009, 6:02:50 AM10/6/09
to ninject-dev
No it didn't, but as I'm hosting in IIS (using WAS) then scoping per
HttpContext works just fine for me. However I'm still trying to
figure out a WCFier way (it is a word, I looked it up) for scoping
that would work with other hosting options. It may be that per thread
would work in other scenarios I guess but as with anything in WCF
there are just so many ways you could configure everything that things
like this become really difficult to do in any way that adapts to all
of the options (especially instancing and concurrency options).

On Oct 5, 8:24 pm, Ian Davis <ian.f.da...@gmail.com> wrote:
> Did switching to  ctx=>OperationContext.Current resolve your issue?
>
> -Ian
>
>
>
>
>
> On Fri, Oct 2, 2009 at 5:46 AM, Chris <cmdrk...@googlemail.com> wrote:
>
> > Hey All,
>
> >           I'm currently using the WCF extensions found at
> >http://github.com/idavis/ninject.extensions.wcfand it seems to be

Guido Ziliotti

unread,
Oct 6, 2009, 7:53:11 AM10/6/09
to ninje...@googlegroups.com
> No it didn't
You mean the Scope right?

I was talking about your Ninject fix. That works fine as far as I have tested.

Aboout Scope - actually Nhibernate as far as I'm concerned - I am still trying some experiments.


On Tue, Oct 6, 2009 at 12:02 PM, Chris <cmdr...@googlemail.com> wrote:

No it didn't , but as I'm hosting in IIS (using WAS) then scoping per

Guido Ziliotti

unread,
Oct 6, 2009, 9:34:42 AM10/6/09
to ninje...@googlegroups.com
After some blunders I had my same old implementation working on WCF with NHibernate.
Of course this is no solution to what Ian is working on, but hopefully somebody will find it's a nice recipie.

It's very trivial but I would like to share my humble idea and maybe have some feedback.

Limitations: I am ok with Per Call Isolation and I am ok with dto, I don't see any reason for sharing
entities between service and service clients.

So solution is: just use a tiny wrapper around NhibernateUnitOfWork - my name for that is PersistenceScope.
I think this is a nice way to achive per call isolation, it is not focused on WCF, it is more general.
It simply solves the problem of having an easy access to Nhibernate Session through NhibernateUnitOfWork
and adds some syntactic sugar - PersistenceScope. PersistenceScope is just a way of reaching Nhibernate Session,
and ORMUnitOfWork is another one.They both rely on NhibernateUnitOfWork but they don't know each other.
The important point is that you are free to use PersistenceScope in your code just with

using(var persistence=new PersistenceScope() ){...}


and you can call all your repository inside the brackets.

After all it seems to me that a good number of blogs about Nhibernate and WCF are doing 2 things at once: one is building a DI-IOC machinery, second one is tiing this machinery to producing some NhibernateSessionFactory. Since
NhibernateUnitOfWork is already out there - and helps with the second point - this can be splitted in two separte concerns.
As to point one... Ninject.Extensions.Wcf comes to mind.

Guido.

Content of attached file follows. It just collects the involved classes. Ninject Bindings ommitted and self-evident
hopefully.
 
//the Service
public class NhiPerCallbOnWcf : INhibNhiPerCallbOnWcf{
    #region INhibNhiPerCallbOnWcf Members

    public dto.Whatever GetWhateverByName(string name){
        using (var persistence= new PersistenceScope()) {
            var we=WhateverRepository.Query.Where(x => x.Name == name).FirstOrDefault();
            if(we==null) return null;
            var dto= new dto.Whatever { Name = we.Nome };
            return dto;
        }
    }

    #endregion

    public Nhib(IWhateverRepository whateverRepository, IComuneRepository comuneRepository ) {
        if(whateverRepository==null) throw new ArgumentNullException("whateverRepository");
        WhateverRepository = whateverRepository;
    }
  
    #region INhibNhiPerCallbOnWcf Members
    private IWhateverRepository WhateverRepository{get; set;}   
    #endregion
}

//The Repository
public class WhateverRepository:IWhateverRepository{
   
    public IQueryable<Whatever> Query{
        get { return Session.Linq<Whatever>(); }
    }
    //and more

    public ComuneRepository(IORMSessionProvider ormSessionProvider) {
        if(ormSessionProvider==null) throw new ArgumentNullException("ormSessionProvider");
        IOrmSp = ormSessionProvider;
    }

    #region membri
    private IORMSessionProvider IOrmSp { get; set; }
    private ISession Session { get { return IOrmSp.CurrentSession; } }
    #endregion
}

//The Session Provider. Just uses NHibernateUnitOfWork
public class ORMUnitOfWork:IORMSessionProvider{
    #region IORMSessionProvider Members

    public NHibernate.ISession CurrentSession{
        get { return NHibernateUnitOfWork.UnitOfWork.CurrentSession; }       
    }

    #endregion
}
//The Scope. PesistenceScope. This Kicks in an active -started - unit of work
public class PersistenceScope:IPersistenceScope{
    public PersistenceScope() {
        StartedUnitOfWork = NHibernateUnitOfWork.UnitOfWork.Start();
    }
    #region IPersistenceScope Members

    public ITransaction BeginTransaction(){
        var tran=StartedUnitOfWork.BeginTransaction();
        return new Transaction(tran);
    }

    public ITransaction BeginTransaction(System.Data.IsolationLevel isolationLevel){
        var tran = StartedUnitOfWork.BeginTransaction(isolationLevel);
        return new Transaction(tran);
    }

    public void Flush(){
        StartedUnitOfWork.Flush();
    }

    public bool IsInActiveTransaction{
        get { return StartedUnitOfWork.IsInActiveTransaction; }
    }

    #endregion

    #region IDisposable Members

    public void Dispose(){
        StartedUnitOfWork.Dispose();
    }

    #endregion

    private NHibernateUnitOfWork.IUnitOfWork StartedUnitOfWork { get; set; }

}




On Tue, Oct 6, 2009 at 12:02 PM, Chris <cmdr...@googlemail.com> wrote:
NhiPerCallOnWcf.cs

Ian Davis

unread,
Oct 6, 2009, 9:46:02 AM10/6/09
to ninje...@googlegroups.com
If you really need PerRequest, Timo has a blog article about enabling
asp.net compatibility in wcf that may help.

http://theiterator.com/2009/10/ninject-wcf/
Reply all
Reply to author
Forward
0 new messages