What is WCF RIA Commanding - wcf

What is WCF RIA Commanding? Is that even the proper name?
I have a silverlight application in which I want to use command binding to call methods on the webserver; however I'm unsure as to how to go about creating such a class and method so that it can be picked up by RIA and be used in the silverlight XAML; whiout any code behind.

a 'command' in the context of a Silverlight (or WPF) application is a class that implements the ICommand interface.
It is used to bind code in ViewModels to controls in Views.
Just about all the decent MVVM frameworks contain them (PRISM has DelegateCommand, MvvmLight has RelayCommand, etc) but it's not too hard to write your own...
Example usage:
in XAML:
<Button Command="{Binding GetCommand}" Content="Get" />
then in the ViewModel (bound to the View's DataContext)
public ICommand GetCommand
{
get
{
if (_getCommand == null) _getCommand = new RelayCommand(GetHandler, CanGetPredicate);
return _getCommand;
}
}
private void GetHandler()
{
// Do the work here - call into the server, or whatever.
}
private bool CanGetPredicate()
{
// work out if it is valid for this to be called or not
return (someRule == true); // or whatever
}

Related

Access to container of Simple Injector MVC views

In a Sitecore project I've integrated Simple Injector using this article
It uses sitecore pipelines and then uses a method in App_start
namespace BBC.App_Start
{
public class SimpleInjector : IPackage
{
public void RegisterServices(Container container)
{
GetContainer.RegisterServices(container);
container.Register(() => new SitecoreContext(), Lifestyle.Scoped);
container.Register(() => new Container(), Lifestyle.Singleton);
}
}
}
Simply I can inject container into controller constructor but can't have container in View files.
I tried to declare a static property in App-start and save container to it. but still I'm getting no registration type in Views
What is the best way to have container object in views?
As Stephen suggests in his comment, the literal answer to your question is "you shouldn't do that - because it's not really the way MVC and DI are supposed to work". The more detailed answer goes something like this:
The job of your view is to present data that it has been passed via the Model. Views should not really contain logic. Very simple stuff like "if flag is false, hide this block of mark-up" is ok, but the more complex code to work out what the value of the flag is shouldn't be in the view.
MVC tries to make our website code better by encouraging you to separate presentation (the View) from data (the Model) and logic (the Controller). This should make our code easier to work with - So if you have processing that needs doing, then it should really be happening when your controller method runs.
If your view requires some special data, best practice suggests it should work it out in the controller method and pass it to the view in the model. The code might look more like this:
public class MyModel
{
public string SpecialData { get; set; }
}
public class MyController : Controller
{
public ActionResult DoSomething()
{
// do whatever processing is needed
var somethingCalculate = resultFromYourOtherObject();
// do other stuff
var model = new MyModel() { SpecialData = somethingCalculated };
return View(model);
}
}
And then the View just needs to accept the MyModel class as its model, and render the SpecialData property - no logic required.
I think also it's considered a bad idea to have calls to fetch objects from your DI container spread about your codebase. For MVC apps, generally your DI container gets wired in to the process of creating a controller for a request when the app starts up. Rather than passing about a DI Container into your controllers, the DI framework extends the Controller-creation process, and the container isn't exposed outside of this. When the MVC runtime needs to create a controller, the controller-creation logic uses the DI framework to fetch objects for all the controller's dependencies.
Without more detail about what you actually want to achieve, it's difficult to say what the "right" approach to creating your object(s) here is, but the two most common patterns are probably:
1) Constructor injection: Your controller has a parameter which accepts the object required. The DI container creates this object for you at the point where it creates the controller, so your controller gets all its dependencies when it is created. Good for: scenarios where you know how to create the object at the beginning of the request.
public interface IMySpecialObject
{
string DoSomething();
}
public class MyController : Controller
{
private IMySpecialObject _specialObject;
public MyController(IMySpecialObject specialObject)
{
_specialObject = specialObject;
}
public ActionResult RenderAView()
{
// do some stuff
var data = _specialObject.DoSomething();
return View(data);
}
}
As long as IMySpecialObject and a concrete implementation for it are registered with your DI container when your app starts up, all is well.
2) Factory classes: Sometimes, however, the object in question might be optional, or it might require data that's not available at controller-creation time to create it. In that case, your DI framework could pass in a Factory object to your controller, and this is used to do the construction of the special object later.
public interface ISpecialFactory
{
ISpecialObject CreateSpecialObject(object data);
}
public class MyController : Controller
{
private IMySpecialFactory _specialFactory;
public MyController(IMySpecialFactory specialFactory)
{
_specialFactory = specialFactory;
}
public ActionResult RenderAView()
{
// do some stuff
if( requireSpecialObject )
{
var data = getSomeData();
var specialObject = _specialFactory.CreateSpecialObject(data);
var data = _specialObject.DoSomething();
return View(data);
}
return View("someOtherView");
}
}
But a good book on using DI may suggest other approaches that fit your specific problem better.

Configuring the timeout for a WCF RIA Services call from a Silverlight 3 client

I'm using the WCF RIA Services Beta with Silverlight 3.0 and I want to be able to configure the timeout from the client. I know that the underlying technology is WCF and the default timeout seems to be 60 seconds as I would expect.
Is there an easy way to control this and other WCF settings?
My first thought is to try the DomainContext OnCreated hook point which was mentioned in the RIA Services Overview pdf file that was available prior to RIA Services going beta. The MSDN documentation for the DomainContext object no longer mentions the method although it is still there? I'm not sure if this is a case of the documentation lagging behind or an indication that I shouldn't use this extensibility point.
namespace Example.UI.Web.Services
{
public sealed partial class CustomDomainContext
{
partial void OnCreated()
{
// Try and get hold of the WCF config from here
}
}
}
http://blogs.objectsharp.com/CS/blogs/dan/archive/2010/03/22/changing-timeouts-in-wcf-ria-services-rc.aspx
Either one line after domain context creation:
((WebDomainClient<LibraryDomainContext.ILibraryDomainServiceContract>)this.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
or a partial class
public partial class LibraryDomainContext
{
partial void OnCreated()
{
if(DesignerProperties.GetIsInDesignMode(App.Current.RootVisual))
((WebDomainClient<LibraryDomainContext.ILibraryDomainServiceContract>)this.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
}
}
For reference the code below nearly works but you can't access a private member using reflection in Silverlight. Wouldn't have been happy with this hack though anyway. Interesting to note that there is a WebDomainClient contructor that takes a Binding parameter private WebDomainClient(Uri serviceUri, bool usesHttps, Binding binding) but the XML Comment for this states Private constructor. Should be made public once we have an end-to-end extensibility story on top of WCF. Looks like I'll have to wait a while before they get to exposing this kind of configuration to us.
public sealed partial class AppDomainContext
{
partial void OnCreated()
{
var webDomainClient = ((WebDomainClient<AppDomainContext.IAppDomainServiceContract>)this.DomainClient);
// Can I use reflection here to get hold of the Binding
var bindingField = webDomainClient.GetType().GetField("_binding", BindingFlags.NonPublic | BindingFlags.Instance);
// In Silverlight, the value of a private field cannot be access by using reflection so the GetValue call throws an exception
// http://msdn.microsoft.com/en-us/library/4ek9c21e%28VS.95%29.aspx
var binding = bindingField.GetValue(webDomainClient) as System.ServiceModel.Channels.Binding;
// So near yet so far!!
binding.SendTimeout = new TimeSpan(0,0,1);
}
}

WCF RIA Services - loading data and binding

I've just been toying around with the new WCF RIA Services Beta for Silverlight this evening. So far it looks nice, but I've come across a few barriers when trying to retrieve data and exposing it to the UI via binding.
First of all, how am I able to get a single integer or string value from my service? Say if I have this method on my domainservice:
public int CountEmployees()
{
return this.ObjectContext.Employees.Count();
}
How am I able to make a call to this and bind the result to, say, a TextBlock?
Also, is there any way to make a custom layout for binding data? I feel a little "limited" to ListBox, DataGrid and such. How is it possible to, i.e., make a Grid with a stackpanel inside and have some TextBlocks showing the bound data? If it's possible at all with WCF RIA Services :)
Thanks a lot in advance.
To do custom methods you can use the Invoke attribute.
In the server side you declare in a domain service like this
[EnableClientAccess]
public class EmployeesService : DomainService
{
[Invoke]
public int CountEmployees()
{
return this.ObjectContext.Employees.Count();
}
}
And in your Client-side you can use it like this
EmployeesContext context = new EmployeesContext();
InvokeOperation<int> invokeOp = context.CountEmployees(OnInvokeCompleted, null);
private void OnInvokeCompleted(InvokeOperation<int> invOp)
{
if (invOp.HasError)
{
MessageBox.Show(string.Format("Method Failed: {0}", invOp.Error.Message));
invOp.MarkErrorAsHandled();
}
else
{
result = invokeOp.Value;
}
}
For the second question, you are not limited with binding. The object you get from your context can be binded with any elements you want.
You can name your class with schema classname.shared.cs and this code will also available in silverlight application.
Using Silverlight/WPF databinding engine you can build any fancy layout using datagrid / listbox containers and regular controls like textbox/label and apply your own style/skin - Example.
EDIT
Shared code cannot contain any database-related functions, only some plain calculations. If you want to retrieve this value from server then you need to make WCF method call.
At serverside you create DomainService implementation:
[EnableClientAccess()]
public class HelloWorld : DomainService
{
public string SayHello()
{
return "Test";
}
}
Then you can use this at client:
HelloWorld context = new HelloWorld();
context.SayHello(x => context_SayHelloCompleted(x), null);
void context_SayHelloCompleted(System.Windows.Ria.InvokeOperation<string> op)
{
HelloTextBlock.Text = op.Value;
}
All dirty work with making HelloWorld class available at Silverlight client is done by Visual Studio. Check hidden generated code folder.
[Invoke] attribute is obsolete in newest release of RIA services.

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);
}
}
}

Decoupling Silverlight client from service reference generated class

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