Decoupling Silverlight client from service reference generated class - wcf

I am researching Prism v2 by going thru the quickstarts. And I have created a WCF service with the following signature:
namespace HelloWorld.Silverlight.Web
{
[ServiceContract(Namespace = "http://helloworld.org/messaging")]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class HelloWorldMessageService
{
private string message = "Hello from WCF";
[OperationContract]
public void UpdateMessage(string message)
{
this.message = message;
}
[OperationContract]
public string GetMessage()
{
return message;
}
}
}
When I add a service reference to this service in my silverlight project it generates an interface and a class:
[System.ServiceModel.ServiceContractAttribute
(Namespace="http://helloworld.org/messaging",
ConfigurationName="Web.Services.HelloWorldMessageService")]
public interface HelloWorldMessageService {
[System.ServiceModel.OperationContractAttribute
(AsyncPattern=true,
Action="http://helloworld.org/messaging/HelloWorldMessageService/UpdateMessage",
ReplyAction="http://helloworld.org/messaging/HelloWorldMessageService/UpdateMessageResponse")]
System.IAsyncResult BeginUpdateMessage(string message, System.AsyncCallback callback, object asyncState);
void EndUpdateMessage(System.IAsyncResult result);
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://helloworld.org/messaging/HelloWorldMessageService/GetMessage", ReplyAction="http://helloworld.org/messaging/HelloWorldMessageService/GetMessageResponse")]
System.IAsyncResult BeginGetMessage(System.AsyncCallback callback, object asyncState);
string EndGetMessage(System.IAsyncResult result);
}
public partial class HelloWorldMessageServiceClient : System.ServiceModel.ClientBase<HelloWorld.Core.Web.Services.HelloWorldMessageService>, HelloWorld.Core.Web.Services.HelloWorldMessageService {
{
// implementation
}
I'm trying to decouple my application by passing around the interface instead of the concrete class. But I'm having difficulty finding examples of how to do this. When I try and call EndGetMessage and then update my UI I get an exception about updating the UI on the wrong thread. How can I update the UI from a background thread?
I tried but I get UnauthorizedAccessException : Invalid cross-thread access.
string messageresult = _service.EndGetMessage(result);
Application.Current.RootVisual.Dispatcher.BeginInvoke(() => this.Message = messageresult );
The exception is thrown by Application.Current.RootVisual.

Here is something I like doing... The service proxy is generated with an interface
HelloWorldClient : IHelloWorld
But the problem is that IHelloWorld does not include the Async versions of the method. So, I create an async interface:
public interface IHelloWorldAsync : IHelloWorld
{
void HelloWorldAsync(...);
event System.EventHandler<HelloWorldEventRgs> HelloWorldCompleted;
}
Then, you can tell the service proxy to implement the interface via partial:
public partial class HelloWorldClient : IHelloWorldAsync {}
Because the HelloWorldClient does, indeed, implement those async methods, this works.
Then, I can just use IHelloWorldAsync everywhere and tell the UnityContainer to use HelloWorldClient for IHelloWorldAsync interfaces.

Ok, I have been messing with this all day and the solution is really much more simple than that. I originally wanted to call the methods on the interface instead of the concreate class. The interface generated by proxy class generator only includes the BeginXXX and EndXXX methods and I was getting an exception when I called EndXXX.
Well, I just finished reading up on System.Threading.Dispatcher and I finally understand how to use it. Dispatcher is a member of any class that inherits from DispatcherObject, which the UI elements do. The Dispatcher operates on the UI thread, which for most WPF applications there is only 1 UI thread. There are exceptions, but I believe you have to do this explicitly so you'll know if you're doing it. Otherwise, you've only got a single UI thread. So it is safe to store a reference to a Dispatcher for use in non-UI classes.
In my case I'm using Prism and my Presenter needs to update the UI (not directly, but it is firing IPropertyChanged.PropertyChanged events). So what I have done is in my Bootstrapper when I set the shell to Application.Current.RootVisual I also store a reference to the Dispatcher like this:
public class Bootstrapper : UnityBootstrapper
{
protected override IModuleCatalog GetModuleCatalog()
{
// setup module catalog
}
protected override DependencyObject CreateShell()
{
// calling Resolve instead of directly initing allows use of dependency injection
Shell shell = Container.Resolve<Shell>();
Application.Current.RootVisual = shell;
Container.RegisterInstance<Dispatcher>(shell.Dispatcher);
return shell;
}
}
Then my presenter has a ctor which accepts IUnityContainer as an argument (using DI) then I can do the following:
_service.BeginGetMessage(new AsyncCallback(GetMessageAsyncComplete), null);
private void GetMessageAsyncComplete(IAsyncResult result)
{
string output = _service.EndGetMessage(result);
Dispatcher dispatcher = _container.Resolve<Dispatcher>();
dispatcher.BeginInvoke(() => this.Message = output);
}
This is sooooo much simpler. I just didn't understand it before.

Ok, so my real problem was how to decouple my dependency upon the proxy class created by my service reference. I was trying to do that by using the interface generated along with the proxy class. Which could have worked fine, but then I would have also had to reference the project which owned the service reference and so it wouldn't be truly decoupled. So here's what I ended up doing. It's a bit of a hack, but it seems to be working, so far.
First here's my interface definition and an adapter class for the custom event handler args generated with my proxy:
using System.ComponentModel;
namespace HelloWorld.Interfaces.Services
{
public class GetMessageCompletedEventArgsAdapter : System.ComponentModel.AsyncCompletedEventArgs
{
private object[] results;
public GetMessageCompletedEventArgsAdapter(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState)
{
this.results = results;
}
public string Result
{
get
{
base.RaiseExceptionIfNecessary();
return ((string)(this.results[0]));
}
}
}
/// <summary>
/// Create a partial class file for the service reference (reference.cs) that assigns
/// this interface to the class - then you can use this reference instead of the
/// one that isn't working
/// </summary>
public interface IMessageServiceClient
{
event System.EventHandler<GetMessageCompletedEventArgsAdapter> GetMessageCompleted;
event System.EventHandler<AsyncCompletedEventArgs> UpdateMessageCompleted;
void GetMessageAsync();
void GetMessageAsync(object userState);
void UpdateMessageAsync(string message);
void UpdateMessageAsync(string message, object userState);
}
}
Then I just needed to create a partial class which extends the proxy class generated by the service reference:
using System;
using HelloWorld.Interfaces.Services;
using System.Collections.Generic;
namespace HelloWorld.Core.Web.Services
{
public partial class HelloWorldMessageServiceClient : IMessageServiceClient
{
#region IMessageServiceClient Members
private event EventHandler<GetMessageCompletedEventArgsAdapter> handler;
private Dictionary<EventHandler<GetMessageCompletedEventArgsAdapter>, EventHandler<GetMessageCompletedEventArgs>> handlerDictionary
= new Dictionary<EventHandler<GetMessageCompletedEventArgsAdapter>, EventHandler<GetMessageCompletedEventArgs>>();
/// <remarks>
/// This is an adapter event which allows us to apply the IMessageServiceClient
/// interface to our MessageServiceClient. This way we can decouple our modules
/// from the implementation
/// </remarks>
event EventHandler<GetMessageCompletedEventArgsAdapter> IMessageServiceClient.GetMessageCompleted
{
add
{
handler += value;
EventHandler<GetMessageCompletedEventArgs> linkedhandler = new EventHandler<GetMessageCompletedEventArgs>(HelloWorldMessageServiceClient_GetMessageCompleted);
this.GetMessageCompleted += linkedhandler;
handlerDictionary.Add(value, linkedhandler);
}
remove
{
handler -= value;
EventHandler<GetMessageCompletedEventArgs> linkedhandler = handlerDictionary[value];
this.GetMessageCompleted -= linkedhandler;
handlerDictionary.Remove(value);
}
}
void HelloWorldMessageServiceClient_GetMessageCompleted(object sender, GetMessageCompletedEventArgs e)
{
if (this.handler == null)
return;
this.handler(sender, new GetMessageCompletedEventArgsAdapter(new object[] { e.Result }, e.Error, e.Cancelled, e.UserState));
}
#endregion
}
}
This is an explicit implementation of the event handler so I can chain together the events. When user registers for my adapter event, I register for the actual event fired. When the event fires I fire my adapter event. So far this "Works On My Machine".

Passing around the interface (once you have instantiated the client) should be as simply as using HelloWorldMessageService instead of the HelloWorldMessageServiceClient class.
In order to update the UI you need to use the Dispatcher object. This lets you provide a delegate that is invoked in the context of the UI thread. See this blog post for some details.

You can make this much simpler still.
The reason the proxy works and your copy of the contract does not is because WCF generates the proxy with code that "Posts" the callback back on the calling thread rather than making the callback on the thread that is executing when the service call returns.
A much simplified, untested, partial implementation to give you the idea of how WCF proxies work looks something like:
{
var state = new
{
CallingThread = SynchronizationContext.Current,
Callback = yourCallback
EndYourMethod = // assign delegate
};
yourService.BeginYourMethod(yourParams, WcfCallback, state);
}
private void WcfCallback(IAsyncResult asyncResult)
{
// Read the result object data to get state
// Call EndYourMethod and block until the finished
state.Context.Post(state.YourCallback, endYourMethodResultValue);
}
The key is the storing of the syncronizationContext and calling the Post method. This will get the callback to occur on the same thread as Begin was called on. It will always work without involving the Dispatcher object provided you call Begin from your UI thread. If you don't then you are back to square one with using the Dispatcher, but the same problem will occur with a WCF proxy.
This link does a good job of explaining how to do this manually:
http://msdn.microsoft.com/en-us/library/dd744834(VS.95).aspx

Just revisiting old posts left unanswered where I finally found an answer. Here's a post I recently wrote that goes into detail about how I finally handled all this:
http://www.developmentalmadness.com/archive/2009/11/04/mvvm-with-prism-101-ndash-part-6-commands.aspx

Related

Looking for a Ninject scope that behaves like InRequestScope

On my service layer I have injected an UnitOfWork and 2 repositories in the constructor. The Unit of Work and repository have an instance of a DbContext I want to share between the two of them. How can I do that with Ninject ? Which scope should be considered ?
I am not in a web application so I can't use InRequestScope.
I try to do something similar... and I am using DI however, I need my UoW to be Disposed and created like this.
using (IUnitOfWork uow = new UnitOfWorkFactory.Create())
{
_testARepository.Insert(a);
_testBRepository.Insert(b);
uow.SaveChanges();
}
EDIT: I just want to be sure i understand… after look at https://github.com/ninject/ninject.extensions.namedscope/wiki/InNamedScope i though about my current console application architecture which actually use Ninject.
Lets say :
Class A is a Service layer class
Class B is an unit of work which take into parameter an interface (IContextFactory)
Class C is a repository which take into parameter an interface (IContextFactory)
The idea here is to be able to do context operations on 2 or more repository and using the unit of work to apply the changes.
Class D is a context factory (Entity Framework) which provide an instance (keep in a container) of the context which is shared between Class B et C (.. and would be for other repositories aswell).
The context factory keep the instance in his container so i don’t want to reuse this instance all the name since the context need to be disposed at the end of the service operaiton.. it is the main purpose of the InNamedScope actually ?
The solution would be but i am not sure at all i am doing it right, the services instance gonna be transcient which mean they actually never disposed ? :
Bind<IScsContextFactory>()
.To<ScsContextFactory>()
.InNamedScope("ServiceScope")
.WithConstructorArgument(
"connectionString",
ConfigurationUtility.GetConnectionString());
Bind<IUnitOfWork>().To<ScsUnitOfWork>();
Bind<IAccountRepository>().To<AccountRepository>();
Bind<IBlockedIpRepository>().To<BlockedIpRepository>();
Bind<IAccountService>().To<AccountService>().DefinesNamedScope("ServiceScope");
Bind<IBlockedIpService>().To<BlockedIpService>().DefinesNamedScope("ServiceScope");
UPDATE: This approach works against NuGet current, but relies in an anomaly in the InCallscope implementation which has been fixed in the current Unstable NuGet packages. I'll be tweaking this answer in a few days to reflect the best approach after some mulling over. NB the high level way of structuring stuff will stay pretty much identical, just the exact details of the Bind<DbContext>() scoping will work. (Hint: CreateNamedScope in unstable would work or one could set up the Command Handler as DefinesNamedScope. Reason I dont just do that is that I want to have something that composes/plays well with InRequestScope)
I highly recommend reading the Ninject.Extensions.NamedScope integration tests (seriously, find them and read and re-read them)
The DbContext is a Unit Of Work so no further wrapping is necessary.
As you want to be able to have multiple 'requests' in flight and want to have a single Unit of Work shared between them, you need to:
Bind<DbContext>()
.ToMethod( ctx =>
new DbContext(
connectionStringName: ConfigurationUtility.GetConnectionString() ))
.InCallScope();
The InCallScope() means that:
for a given object graph composed for a single kernel.Get() Call (hence In Call Scope), everyone that requires an DbContext will get the same instance.
the IDisposable.Dispose() will be called when a Kernel.Release() happens for the root object (or a Kernel.Components.Get<ICache>().Clear() happens for the root if it is not .InCallScope())
There should be no reason to use InNamedScope() and DefinesNamedScope(); You don't have long-lived objects you're trying to exclude from the default pooling / parenting / grouping.
If you do the above, you should be able to:
var command = kernel.Get<ICommand>();
try {
command.Execute();
} finally {
kernel.Components.Get<ICache>().Clear( command ); // Dispose of DbContext happens here
}
The Command implementation looks like:
class Command : ICommand {
readonly IAccountRepository _ar;
readonly IBlockedIpRepository _br;
readonly DbContext _ctx;
public Command(IAccountRepository ar, IBlockedIpRepository br, DbContext ctx){
_ar = ar;
_br = br;
_ctx = ctx;
}
void ICommand.Execute(){
_ar.Insert(a);
_br.Insert(b);
_ctx.saveChanges();
}
}
Note that in general, I avoid having an implicit Unit of Work in this way, and instead surface it's creation and Disposal. This makes a Command look like this:
class Command : ICommand {
readonly IAccountService _as;
readonly IBlockedIpService _bs;
readonly Func<DbContext> _createContext;
public Command(IAccountService #as, IBlockedIpServices bs, Func<DbContext> createContext){
_as = #as;
_bs = bs;
_createContext = createContext;
}
void ICommand.Execute(){
using(var ctx = _createContext()) {
_ar.InsertA(ctx);
_br.InsertB(ctx);
ctx.saveChanges();
}
}
This involves no usage of .InCallScope() on the Bind<DbContext>() (but does require the presence of Ninject.Extensions.Factory's FactoryModule to synthesize the Func<DbContext> from a straightforward Bind<DbContext>().
As discussed in the other answer, InCallScope is not a good approach to solving this problem.
For now I'm dumping some code that works against the latest NuGet Unstable / Include PreRelease / Instal-Package -Pre editions of Ninject.Web.Common without a clear explanation. I will translate this to an article in the Ninject.Extensions.NamedScope wiki at some stagehave started to write a walkthrough of this technique in the Ninject.Extensions.NamedScope wiki's CreateNamedScope/GetScope article.
Possibly some bits will become Pull Request(s) at some stage too (Hat tip to #Remo Gloor who supplied me the outline code). The associated tests and learning tests are in this gist for now), pending packaging in a proper released format TBD.
The exec summary is you Load the Module below into your Kernel and use .InRequestScope() on everything you want created / Disposed per handler invocation and then feed requests through via IHandlerComposer.ComposeCallDispose.
If you use the following Module:
public class Module : NinjectModule
{
public override void Load()
{
Bind<IHandlerComposer>().To<NinjectRequestScopedHandlerComposer>();
// Wire it up so InRequestScope will work for Handler scopes
Bind<INinjectRequestHandlerScopeFactory>().To<NinjectRequestHandlerScopeFactory>();
NinjectRequestHandlerScopeFactory.NinjectHttpApplicationPlugin.RegisterIn( Kernel );
}
}
Which wires in a Factory[1] and NinjectHttpApplicationPlugin that exposes:
public interface INinjectRequestHandlerScopeFactory
{
NamedScope CreateRequestHandlerScope();
}
Then you can use this Composer to Run a Request InRequestScope():
public interface IHandlerComposer
{
void ComposeCallDispose( Type type, Action<object> callback );
}
Implemented as:
class NinjectRequestScopedHandlerComposer : IHandlerComposer
{
readonly INinjectRequestHandlerScopeFactory _requestHandlerScopeFactory;
public NinjectRequestScopedHandlerComposer( INinjectRequestHandlerScopeFactory requestHandlerScopeFactory )
{
_requestHandlerScopeFactory = requestHandlerScopeFactory;
}
void IHandlerComposer.ComposeCallDispose( Type handlerType, Action<object> callback )
{
using ( var resolutionRoot = _requestHandlerScopeFactory.CreateRequestHandlerScope() )
foreach ( object handler in resolutionRoot.GetAll( handlerType ) )
callback( handler );
}
}
The Ninject Infrastructure stuff:
class NinjectRequestHandlerScopeFactory : INinjectRequestHandlerScopeFactory
{
internal const string ScopeName = "Handler";
readonly IKernel _kernel;
public NinjectRequestHandlerScopeFactory( IKernel kernel )
{
_kernel = kernel;
}
NamedScope INinjectRequestHandlerScopeFactory.CreateRequestHandlerScope()
{
return _kernel.CreateNamedScope( ScopeName );
}
/// <summary>
/// When plugged in as a Ninject Kernel Component via <c>RegisterIn(IKernel)</c>, makes the Named Scope generated during IHandlerFactory.RunAndDispose available for use via the Ninject.Web.Common's <c>.InRequestScope()</c> Binding extension.
/// </summary>
public class NinjectHttpApplicationPlugin : NinjectComponent, INinjectHttpApplicationPlugin
{
readonly IKernel kernel;
public static void RegisterIn( IKernel kernel )
{
kernel.Components.Add<INinjectHttpApplicationPlugin, NinjectHttpApplicationPlugin>();
}
public NinjectHttpApplicationPlugin( IKernel kernel )
{
this.kernel = kernel;
}
object INinjectHttpApplicationPlugin.GetRequestScope( IContext context )
{
// TODO PR for TrgGetScope
try
{
return NamedScopeExtensionMethods.GetScope( context, ScopeName );
}
catch ( UnknownScopeException )
{
return null;
}
}
void INinjectHttpApplicationPlugin.Start()
{
}
void INinjectHttpApplicationPlugin.Stop()
{
}
}
}

Ninject Interception: Service calling intercepted method not being intercepted when called within itself

I have a service class injected with Ninject 3.0. I have set it up so it's proxy is a class proxy rather than an interface proxy. The service has 2 methods, a first one returning broad result and a second one calling the first one and filtering it. I added a interceptor to cache the result of the first method.
The interception works fine when I call the first method from outside the service.
The problem is that when the interceptor invokes the second method, it invokes it through the service itself and not through the proxy, resulting in my call to the first method from my service not being intercepted, therefor not cached.
How can I get this to work?
UPDATE: Added sample code
This is on the top of my head so sorry if anything doesn't seem to compile
Here is a sample the service class
public class Service : IService
{
[CacheMethodOutput]
public virtual object[] GetObjects(int x)
{
...
}
public virtual object GetObject(int x, int y)
{
return GetObjects(x).SingleOrDefault(o => o.y == y);
}
}
The CacheMethodOutputAttribute is a simple attribute class
Here is a sample binding (this is the way I make sure to have a class proxy instead of a interface proxy but actually leave the injected reference by interface)
// Binds by type instead of proxy to create a class proxy
Bind<Service>().ToSelf().InSingletonScope().Intercept().With<CacheAttributeInterceptor>()
Bind<IService>().ToMethod<Service>(r => r.Kernel.Get<Service>());
So when I call GetObjects from any class in which the IService is injected, the interceptor is triggered, but it's not triggered from the GetObject method of the Service itself.
The CacheAttributeInterceptor looks like this (but details of implementation is irrelevant):
public class CacheAttributeInterceptor : SimpleInterceptor
{
public ICacheManager CacheManager {get;set;}
public override void BeforeInvoke(IInvocation invocation)
{
if (Attributes.GetCustomAttribute(invocation.Request.Method, typeof(CacheMethodOutputAttribute) != null)
{
string key = GenerateKey(invocation.Request.Method.Name, invocation.Request.Method.Arguments);
object returnValue;
if (!CacheManager.TryGet(key, out returnValue))
{
invocation.Proceed();
returnValue = invocation.ReturnValue;
CacheManager.Add(key, returnValue);
}
else
invocation.ReturnValue = returnValue;
}
else
base.BeforeInvoke(invocation);
}
}
I found the solution / more detail on the problem.
If I remove the virtual modifier on the GetObject method, it will then not be intercepted anymore and when it will call GetObjects, the incerceptor will trigger.
All this got me thinking that if I want both method to be intercepted, I need to make the interceptor work deeply, if this is even possible.

log4net using ThreadContext.Properties in wcf PerSession service

I would like to use the following in my wcf service to log the user in the log message:
log4net.ThreadContext.Properties["user"] = this.currentUser.LoginName;
I have the service set up to run in InstanceContextMode.PerSession. In the initial call to the wcf service I am setting this ThreadContext property to the current user that is logged in but each subsequent call does not log this property.
I'm pretty sure that for each call to the service it's running the task on a different thread even though it's set to use PerSession. I assume it's using a thread pool to process the requests.
Is there a way to set this so that I don't have to do it in every wcf method?
I ran into the same problem and this is how I got it to work. You can use GlobalContext since it will be evaluated for each call anyway.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IMyService
{
//static constructor
static MyService()
{
log4net.Config.XmlConfigurator.Configure();
log4net.GlobalContext.Properties["user"] = new UserLogHelper();
}
...
}
Then you have to define a simple class:
private class UserLogHelper
{
public override string ToString()
{
var instanceContext = OperationContext.Current.InstanceContext;
var myServiceInstance = instanceContext.GetServiceInstance() as MyService;
return myServiceInstance?.currentUser?.LoginName;
}
}
Log4net supports "calculated context values". By using this you could write a class like this:
public class UserNameContext
{
public override string ToString()
{
string userName = ...; // get the name of the current user
return userName;
}
}
If you add this to the global context you can access the property in your appenders (like you are used to). The 'ToString' method will be executed every time and thus you get the correct user name.
More on context values can be found in this great tutorial:
http://www.beefycode.com/post/Log4Net-Tutorial-pt-6-Log-Event-Context.aspx

WCF app in IIS7: Losing singleton instance

I have a WCF application , with multiple WSDL webservices, hosted in IIS7 on Windows Server 2008 64Bit.
The application requires a singleton to be assigned with some configuration values once, when the first webservice method is invoked (no matter what is invoked first).
Edit: The backend of the system requires the use of this singleton approach.
I get the configuration assigned once, but the values become null again....
Here is the code (simplified):
public class SingletonSettings
{
private static readonly SingletonSettings _s;
public SingletonSettings Instance { get {return _s;} }
public object SomeValue { get; set; }
}
public abstract class AbstractWebservice
{
static AbstractWebservice()
{
WebserviceGlobalInitializer.Initialize();
}
}
//Just a webservice
public class Webservice1 : AbstractWebservice, ISomeServiceConctract1
{
public void DoStuff1();
}
//Just a webservice
public class Webservice2 : AbstractWebservice, ISomeServiceConctract2
{
public void DoStuff2();
}
internal class WebserviceGlobalInitializer
{
private static readonly object Lock = new object();
private static bool Initialized = false;
public static void Initialize()
{
lock (Lock)
{
if (!Initialized)
{
InitStuff();
Initialized = true;
}
}
}
private static void InitStuff()
{
string s = SingletonSettings.Instance.SomeValue = "just a ref";
}
}
WebserviceGlobalInitializer.InitStuff() gets invoked only once. Still SingletonSettings.SomeValue becomes null.....
The issue occurs randomly.
I have tried
1) Invoking WebserviceGlobalInitializer.Initialize() from a normal constructor in the base class.
2) Commenting out: Initialized = true; in hope that the settings would then be initialized every time (causing massive overhead, so it would not be a long term solution anyway)
Still the value becomes null.
Any ideas?
With process recycling, all state that is not in session state or application state will disappear into the black hole. This, eye-openingly, includes the static variables, one of which is the singleton instance.
My gut feeling is that the InstanceContextMode of singleton has been implemented as a variable in the ASP.NET Application state. To check this, I will be doing some reflectoring today and will update my answer.
UPDATE
NO IT DOESN'T!!! With process recycling, even if you set the WCF Instancing mode to Single, you lose all state you had with your singleton instance (e.g. counter, whatever) with process recycling.
After a few more days of searching i found the source of the problem. Aliostad's answer gave me a hint.
My webservice uses behavior configurations. One with authentication and one without.
The authentication/session handling is implemented in an IDispatchMessageInspector which is invoked before the webservice is loaded.
The problem occurred when an application that uses my webservice was online when the application pool was recycled. Then application would then a request to a webservice using the authenticated behavior.
The IDispatchMessageInspector implemention would then try to load the settings, but they have not yet been initialized from the static constructor in the webservice....
Thank you for the answers...
You can use the WCF runtime infrastructure to take care of this for you. Try adding the following attribute to the WebService class:
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single)]

Unity: Using same datacontext in application_BeginRequest?

Previously i managed to setup my unity to provide a new DataContext each time to my Repository project. It works great.
But for example, I am in a WCF method which opens up 2 services which in turn opens up 2 repositories (repository pattern).. i was hoping to be able to reuse the same datacontext within the same wcf method.
So i have been looking at RegisterInstance but i check the GetHashCode of the datacontext and its different each time. i thought unity will check the child container first every time which i presume i have an instance setup - see below
Here is my unity that executes once!
container.RegisterType<MyDataContext>(new TransientLifetimeManager(),
new InjectionConstructor())
And then i try and configure in global.asax under Application_BeginRequest - but maybe this is not ideal as it seems to enter multiple times.. even when running the wcf service before someone calls a wcf method
protected void Application_BeginRequest(object sender, EventArgs e)
{
Bootstrapper.ConfigureDataContextContainer();
}
And here is my configureDataContextContainer
public static void ConfigureDataContextContainer()
{
if (childContainer == null) // I have to do this otherwise it executes multiple times.
{
childContainer = Bootstrapper.Container.CreateChildContainer();
childContainer.RegisterInstance<MyDataContext>
(container.Resolve<MyDataContext>()); // I Presume i create an instance here
}
}
As i say in my WCF method i am opening 2 services which in turn opens up "THEIR OWN" Respository which takes in a DataContext - MyDataContext
To fix the problem with the BeginRequest i could register the datacontext as an instance (if it worked :-) ) on every WCF method i have but it seems a bit of a long way round.
Of course its very imported that each connection (not sessions) gets its own DataContext.
I was disposing the datacontext when when i disposed of my repository ... now (if i can get it working) i presume i will need to dispose of this in EndRequest.. otherwise if one service completes and disposes of the DataContext and the other service hasn't finsihed then i am going to get issues.
I hope i have explained this well, :-)
Summary is that each WCF method must use its own datacontext , a web method can call more than 1 service (repository pattern) which in turn will call its repository which expects a datacontext on the constuctor which unity Registers - but currently when in the same WCF method, multiple services call there repositories and they get there own DataContext.
If i can clarify anything please let me know
Thanks
EDIT
Forgot to mention how i am getting unity to resolve things ... I simple call this on the container (not child container) to the service which in turn calls the respository
using (IOfficeService officeService = Bootstrapper.Container.Resolve<IOfficeService >())
{
You are registering the instance in the child container, so you have to use the child container when resolving your service (Also, you should be disposing of your child container on Application_EndRequest):
using (var service = childContainer.Resolve<IOfficeService >())
{
}
However, using a PerRequestLifetimeManager should accomplish the same thing:
Container.RegisterType<MyDataContext>(new PerRequestLifetimeManager());
Here's how I implement it:
public class PerRequestLifetimeManager : LifetimeManager {
private Guid key;
public PerRequestLifetimeManager() {
key = Guid.NewGuid();
}
public override object GetValue() {
if (HttpContext.Current == null) {
return null;
} else {
return HttpContext.Current.Items[key];
}
}
public override void RemoveValue() {
if (HttpContext.Current != null) {
HttpContext.Current.Items.Remove(key);
}
}
public override void SetValue(object newValue) {
if (HttpContext.Current != null) {
HttpContext.Current.Items.Add(key, newValue);
}
}
}