This is my first attempt to use WCF so there may be something fundamentally wrong with this approach - if so I'm happy to switch to a different model. At quick glance, I thought the answer to this question would have worked, but my scenario appears to be different.
I have an ASP.NET MVC website where the controllers access the WCF client class through an intermediate repository. The repository is just a wrapper around the WCF client that instantiates it once and sets the proper endpoint address.
public class WcfRepository : IRepository
{
private MyWCFServiceClient client;
public WcfRepository()
{
client = new MyWCFServiceClient();
}
public bool MyMethod1()
{
return client.MyMethod1();
}
... etc
}
I can access different pages on the website until a seemingly random point where the WCF service will start timing out. It doesn't matter which method I call either - it timesout on different ones. I cannot see any exceptions on the IIS machine hosting the WCF service either; the event log there is empty. A simple method like GetCustomerByName() which worked two minutes earlier will no longer so I think it's more to do with WCF communication rather than the service itself.
If I try to use the WCF Test Client after one of these timeouts occurs, it will also fail. But, if I wait a while (and choose 'start a new proxy') then things will work again.
I'm very confused - should I be creating a new instance of the WCF client each time I want to use it in my repository? Is there another way I should be using the client? Wrapping each call in Open()/Close() doesn't work either since the first call to Close() puts the object in a disposed state.
When you are done with your WCF client, you must explicitly close it because it will otherwise keep a 'connection' open to the service, and there's a (configurable) limit to how many concurrent connection you can have.
Although it is possible to tweak that limit, the correct solution is to create a new WCF client, invoke one or more methods on it and close it again when you are done. This is considered best practice, and should neatly avoid the sort of problems you are currently experiencing.
This means that your implementation should rather go something like this:
public class WcfRepository : IRepository
{
public bool MyMethod1()
{
var client = new MyWCFServiceClient();
try
{
return client.MyMethod1();
}
finally
{
try
{
client.Close();
}
catch(CommunicationException)
{
// handle exception here
}
catch(TimeoutException)
{
// handle exception here
}
}
}
... etc
}
Notice the nasty try/finally construct, which is necessary because Close may throw. Read more about this here.
Related
I am working in a project which needs to communicate with users realtime. Basically I am following "synchronize pages over web api" path which is introducing in this video (also Brad Wilson has a nice video like this one) and the repository here for video.
My question is about mapping application members with their ConnectionIds which is producing by Signalr.
I used to be saving every signalr connection ID in a database table like:
ConnectionID
MemberID
ConnectionStatusID --> Connected(1), Disconnected(2), Reconnecting(3)
I was fetching member's connection IDs in most requests.
Then I decided to change this design. Now I am grouping every member with a unique string when OnConnected and OnDisconnected like this:
public override Task OnConnected()
{
Groups.Add(this.Context.ConnectionId, string.Format("MyHub_{0}",HubUser.MemberID));
return base.OnConnected();
}
public override Task OnDisconnected()
{
Groups.Remove(this.Context.ConnectionId, string.Format("MyHub_{0}",HubUser.MemberID));
return base.OnConnected();
}
Now I am not fetching anything from database about member connection IDs. It is only working over Web API for making synchronization between browser tabs.
I simply show how I am handling incoming Request and using Hub in Web API:
public HttpResponseMessage Example()
{
string msg = "Example to all";
//some other process
//Hub is an instance of a IHubContext
Hub.Clients.Group(string.Format("MyHub_{0}", HubUser.MemberID)).example(msg);
return Request.CreateResponse(HttpStatusCode.OK, msg);
}
So which one do you think is efficient way for using Signalr. What would you suggest is possibly better than these. Is making a dependency between hub and WebApi is a good design choice to go.
And also project will be deployed to multiple servers and Load Balancer will work in front of them (I am going to use Sql Backplane for this). There are few projects which must talk to Web API, indirectly to hub too.
I like your second solution as it should require less DB queries. It is no less efficient for SignalR to send to a group than it is for it to send to a connection id. You just need to ensure your group names (HubUser.MemberID) are unique and non-spoofable.
In SignalR 2.0, we make this pattern even easier: http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections#IUserIdProvider
If your users' MemberIDs match up with their IPrincipal.Identity.Name, then you can just change all your code to use Clients.User(HubUser.MemberID)....
If you don't want to base your SignalR user id on the request's IPrincipal, you can provide your own IUserIdProvider and inject it using SignalR's dependency resolver.
http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection
I'm a beginner with both .NET MVC and Ninject.
Here how I get my Ninject kernel:
using Ninject;
public class NinjectKernel
{
private static IKernel _Instance = new StandardKernel();
public static IKernel getInstance()
{
return _Instance;
}
}
Here's how I save an instance of an object I want to re-use:
(...) NK = NinjectKernel.getInstance();
private Game getGameInstance() {
IGame iGame;
try
{
iGame = NK.Get<IGame>(DefaultGameName);
}
catch
{
NK.Bind<IGame>().To<Game>().InSingletonScope().Named(DefaultGameName)
.WithConstructorArgument("ColorChoiceCount", 12)
.WithConstructorArgument("CodeLength", 6)
.WithConstructorArgument("TurnsToBePlayed", 8)
.WithConstructorArgument("DoubleColorAllowed", true)
;
iGame = NK.Get<IGame>(DefaultGameName);
}
return (Game)iGame;
}
I want the Game object to be re-usable within a use "session", which means that if he leaves the site this instance won't be used again. But in the current situation, while debugging, when I close the application and re-launch it, I always re-get the instance of my previous "session".
I would also like to know if I won't get the same instance for multiple users because I don't want this. (users may be or may not be authentified, right now they aren't at all).
(You may also suggest my a better solution than using a try/catch there, because I'm sure there must be one, but as this works it is not a priority for now.)
Thank you for your help.
You don't have to do any of that. Just use Nuget to install Ninject.MVC3. This will automatically setup the project to use the MVC DependencyResolver API, and it will create a NinjectMVC3.cs file to create your mappings.
You could check this excellent & easy to follow post for the usage of Ninject with MVC 3 / 4 : http://dotnetfever.com/implementing-dependency-injection-in-asp-net-mvc-4-using-ninject-di-container/
I recommend you redesign your web application and avoid reusing the Game Object within a "Session". The reason is that web application is design to be "stateless", which means it shall not remember the user'data accross multiple requests. The stateless nature could help your web application with better performance and better scalability.
If you do need to remember one user's Game object as long as he is in your site, then try to build the Game Object on every request. If the building is very expensive (connecting to database eg.) then use the asp.net cache to store the object for later reuse.
In a word, use cache, not Ninject to preserve the Game Object.
Right now I'm having an issue with a Singleton that I just wrote for use in ASP.NET MVC -- My Singleton looks like this:
public sealed class RequestGenerator : IRequestGenerator
{
// Singleton pattern
private RequestGenerator()
{
requestList = new Stack<Request>();
appSettings = new WebAppSettings();
}
private static volatile RequestGenerator instance = new RequestGenerator();
private static Stack<Request> requestList = new Stack<Request>();
// abstraction layer for accessing web.config
private static IAppSettings appSettings = new WebAppSettings();
// used for "lock"-ing to prevent race conditions
private static object syncRoot = new object();
// public accessor for singleton
public static IRequestGenerator Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new RequestGenerator();
}
}
}
return instance;
}
}
private const string REQUESTID = "RequestID";
// Find functions
private Request FindRequest(string component, string requestId)
private List<Request> FindAllRequests(string component, string requestId)
#region Public Methods required by Interface
// Gets and increments last Request ID from Web.Config, creates new Request, and returns RequestID
public string GetID(string component, string userId)
// Changes state of Request to "submitted"
public void SetID(string component, string requestId)
// Changes state of Request to "success" or "failure" and records result for later output
public void CloseID(string component, string requestId, bool success, string result)
// Verifies that Component has generated a Request of this ID
public bool VerifyID(string component, string requestId)
// Verifies that Component has generated a Request of this ID and is owned by specified UserId
public bool VerifyID(string component, string userId, string requestId)
// Returns State of Request ID (Open, Submitted, etc.)
public Status GetState(string component, string requestId)
// Returns Result String of Success or Failure.
public string GetResult(string component, string requestId)
#endregion
}
And my controller code looks like this:
public ViewResult SomeAction()
{
private IRequestGenerator reqGen = RequestGenerator.Instance;
string requestId = reqGen.GetID(someComponentName, someUserId);
return View(requestId);
}
Everything works okay the first time I hit the controller. "reqGen" is assigned the instance of the Singleton. A new instance of Request is added to the internal list of the Singleton. And then we return a View(). The next time I hit this controller's SomeAction(), I'm expecting the Singleton to contain the List with the instance of SomeClass that I had just added, but instead the List is empty.
What's happened? Has Garbage Collection gobbled up my object? Is there something special I need to consider when implementing the Singleton pattern in ASP.NET MVC?
Thanks!
EDIT: Ahh, the lightbulb just went on. So each new page request takes place in a completely new process! Got it. (my background is in desktop application development, so this is a different paradigm for me...)
EDIT2: Sure, here's some more clarification. My application needed a request number system where something being requested needed a unique ID, but I had no DB available. But it had to be available to every user to log the state of each request. I also realized that it could double as a way to regulate the session, say, if a use double-clicked the request button. A singleton seemed like the way to go, but realizing that each request is in its own process basically eliminates the singleton. And I guess that also eliminates the static class, right?
EDIT3: ok, I've added the actual code that I'm working with (minus the implementation of each Method, for simplicity sake...) I hope this is clearer.
EDIT4: I'm awarding the green check mark to Chris as I'm beginning to realize that an application-level singleton is just like having a Global (and global's are evil, right?) -- All kidding aside, the best option really is to have a DB and SQLite seems like the best fit for now, although I can definitely see myself moving to an Oracle instance in the future. Unfortunately, the best option then would be to use an ORM, but that's another learning curve to climb. bugger.
EDIT5: Last edit, I swear. :-)
So I tried using HttpRuntime.Cache, but was surprised to find that my cache was getting flushed/invalidated constantly and couldn't figure out what was going on. Well, I was getting tripped up by a side-effect of something else I was doing: Writing to "Web.config"
The Answer --> Unbeknownst to me, when "web.config" is altered in anyway, the application is RESTARTED! Yup, everything gets thrown away. My singleton, my cache, everything. Gah. No wonder nothing was working right. Looks like writing back to web.config is generally bad practice which I shall now eschew.
Thanks again to everyone who helped me out with this quandary.
The singleton is specific to the processing instance. A new instance is being generated for each page request. Page requests are generally considered stateless so data from one doesn't just stick around for another.
In order to get this to work at the application level, the instance variable will have to be declared there. See this question for a hint on how to create an application level variable. Note that this would make it available across all requests.. which isn't always what you want.
Of course, if you are trying to implement some type of session state then you might just use session or use some type of caching procedure.
UPDATE
Based on your edits: A static class should not maintain data. It's purpose is to simply group some common methods together, but it shouldn't store data between method calls. A singleton is an altogether different thing in that it is a class that you only want one object to be created for the request.
Neither of those seem to be what you want.
Now, having an application level singleton would be available to the entire application, but that crosses requests and would have to be coded accordingly.
It almost sounds like you are trying to build an in memory data store. You could go down the path of utilizing one of the various caching mechanisms like .NET Page.Cache, MemCache, or Enterprise Library's Caching Application Block.
However, all of those have the problem of getting cleared in the event the worker process hosting the application gets recycled.. Which can happen at the worst times.. And will happen based on random things like memory usage, some timer expired, a certain number of page recompiles, etc.
Instead, I'd highly recommend using some type of persisted storage. Whether that be just xml files that you read/write from or embedding something like SQL Lite into the application. SQL Lite is a very lightweight database that doesn't require installation on the server; you just need the assemblies.
You can use Dependency Injection to control the life of the class. Here's the line you could add in your web.config if you were using Castle Windsor.
<component id="MySingleton" service="IMySingleton, MyInterfaceAssembly"
type="MySingleton, MyImplementationAssembly" lifestyle="Singleton" />
Of course, the topic of wiring up your application to use DI is beyond my answer, but either you're using it and this answer helps you or you can take a peak at the concept and fall in love with it. :)
I have a mvc controller class that uses a WCF service(WSHttpBinding), sometimes multiple calls within one http request, and want to know how expensive it is to create a client for that service. Is it ok to create an instance of the client for every call or should I create a member variable in the class?
public class RingbacksController : Controller
{
private void LoadContactsIntoViewData(int page)
{
RingbackServiceClient client = new RingbackServiceClient();
...
client.Close();
}
private void LoadGroupsIntoViewData(int page)
{
RingbackServiceClient client = new RingbackServiceClient();
...
client.Close();
}
}
or
public class RingbacksController : Controller
{
private RingbackServiceClient client = new RingbackServiceClient();
private void LoadContactsIntoViewData(int page)
{
...
client.Close();
}
private void LoadGroupsIntoViewData(int page)
{
...
client.Close();
}
}
Creating the client is usually not an awful expensive operation - so you should be fine instantiating it whenever you need it (as Steven mentioned, too - if it's faulted due to an error, you'll need to do that anyway).
Should you be using a ChannelFactory to create the channel (that's one of the ways to do it), creating the ChannelFactory on the other hand is a pretty heavyweight and time-intensive operation, so it would be a good idea to hang on to a ChannelFactory instance for as long as you can.
Marc
In the past, I've created a new instance of the ChannelFactory<> and client/proxy for every call to the WCF service. I haven't had any problems with it, especially not for performance. The application I wrote was deployed on an internal company network (local LAN) where about 30 Windows Forms clients would connect to my WCF service.
Have a look at the following question Where to trap failed connection on WCF calling class? and my answer to it. Its basically a wrapper class which handles client/proxy instantiation and does a lot of necessary error handling to overcome certain shortcomings in the design of WCF (more info in the linked question).
You could re-write it or wrap it further in another factory, so that you can cache the ChannelFactory and client/proxy if you are worried about performance. I have "heard" that its a bad idea to cache the ChannelFactory or client/proxy - however, I am open to correction here.
Should you decide to go with a member, please keep in mind that once it gets faulted, all calls afterwards will fail. As for whether it's worth it, I suggest benchmarking.
In CarTrackr project, It use some technique that creates only 1 repository instance for all request in Asp.net Mvc website and uses UnityControllerFactory class to manage all repository instanes(send to requested controller).
Is there any benefit to using single repository instance when compare with creating new repository instance every request?
I know, it may improve overall performance. But, Does it cause any transcation problem?
partial Global.asax
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
RegisterDependencies();
}
protected static void RegisterDependencies() {
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterType<IUserRepository, UserRepository>(new ContextLifetimeManager<IUserRepository>());
container.RegisterType<ICarRepository, CarRepository>(new ContextLifetimeManager<ICarRepository>());
// Set controller factory
ControllerBuilder.Current.SetControllerFactory(
new UnityControllerFactory(container)
);
}
}
partial CarController.cs
[Authorize]
public class CarController : Controller
{
private IUserRepository UserRepository;
private ICarRepository CarRepository;
public CarController(IUserRepository userRepository, ICarRepository carRepository)
{
UserRepository = userRepository;
CarRepository = carRepository;
}
}
Thanks,
Creating a repository instance per request by itself shouldn't cause any performance issue; the repository is often pretty shallow, and when it needs to access data things like connection pooling minimise the cost of establishing actual connections. Object creation is astonishingly cheap, especially for short-lived things like web requests where the object gets collected while still in "generation zero".
As to whether to have a single repository or a repository per instance - that depends on the repository ;-p
The biggest question is: is your repository thread safe? If not: one per request.
Even if it is though; if your repository itself keeps something like a LINQ-to-SQL DataContext (that you synchronize somehow), then you have big problems if you keep this long-term, in particular with the identity manager. You'll quickly use a lot of memory and get stale results. Far form ideal.
With a single repository instance, you will probably also end up with a lot of blocking trying to get thread safety. This can reduce throughput. Conversely, the database itself has good ways of achieving granular locks - which is particularly useful when you consider that often, concurrent requests will be looking at separate tables etc - so no blocking at the database layer. This would be very hard to do just at the repository layer - so you'd probably have to synchronize the entire "fetch" - very bad.
IMO, one per request is fine in most cases. If you want to cache data, do it separately - i.e. not directly on the repository instance.
I think you're misunderstanding whats happening with the ContextLifeTimeManager. By passing the manager into the Register() method your telling Unity to set the caching scope for your repository instance to HttpContext.
It is actually incorrect to say:
It use some technique that creates only 1 repository instance for all request in Asp.net > Mvc website
There is not a repository singleton. Unity is creating one for each request. It sounds like this is actually your desired behavior.
When the manager's scope is set to HttpContext the container looks to HttpContext for an existing instance of the requested type (in this case, your repository). Since the HttpContext is fresh on each request, the container will not have this instance, thus a new one will be created.
When you ask:
Is there any benefit to using single
repository instance when compare with
creating new repository instance every
request?
No.
As far as transaction problems: Threading will def be an issue. The CarRepository appears to be using Linq2Sql or Linq2Entities. Its ctor requires an active datacontext. DataContext is NOT thread safe. If the datacontext is being stored at a scope higher than the current request, there will be problems.
Using the new ContextLifetimeManager());, the lifetime of a repository is limited to one request. This means that evry request each repository is instantiated (if needed) and destroyed once a response has been sent to the client.