Contrary to WPF, Silverlight doesn't really support Commands in the xaml. For example, the Button class doesn't have a Dependency Property called Command that allows to bind to a command. The command pattern is at the heart of the Model-View-ViewModel pattern (M-V-VM), and this pattern is probably the most important in WPF and Silverlight. Thus, we had to find a way to have it in Silverlight!
Recently SOA (service-oriented architecture) has became just another buzzword. Everybody talks about it, books have been written on the subject and most people look at it as a complex technology one should master in order to live an accomplished life.
Thing is, SOA is ridiculously simple. It's just about hiding a set of functionality (service) behind known contracts (most of the time, a single contract - interface, in other words) and defining a generic way of discovering (instantiating or otherwise getting a grab on) those services. The goal is that service consumers (the coder) don't have to bother with details as to what technology the service is written with (.NET, COM, Java, Web Services, name it), where the service's code will execute, how to instantiate such service, what version is this, etc etc. That's it. Simple, I told you.
Now, Foundation supports (and advocates) SOA since the very first day of its creation. As I just demonstrated, SOA definition stands in a single paragraph. Why try to make it any more complicated in the code? Keep it simple, baby!
In the making of TimeTracker, we got to this point where one has to authenticate against the web server. Easy, you put a service behind https, with a method that takes a username and password, and returns something that says if yes or no the authentication negotiation has been successful.
In a normal process, back on the client, you would then create a Principal and put it on the AppDomain so that it's shared amongst all threads. However, you have those two choices: either you wait until the authentication to create your Principal, meaning that no principal is available between application start and authentication negotiation, or you simply replace the Principal object with a new "authenticated" one, with correct roles. Neither of those solutions were satisfying to me. For the first case, I believe that a correctly built application should always have a well-known principal object to put on the current thread, that principal being anonymous until authentication. For the second case, well, I dislike the idea of replacing altogether the object with a new, promoted one. I mean, the principal represents the user that started and runs the application. At time t, that user is anonymous, and at time t+1, it's now authenticated. It's not a new user, it's just the same user with new roles after successful authentication.
So I decided to create the class SecurePrincipal with the method Promote on it. That method takes an array of roles and add those roles to the current principal. I also created a service, called CredentialsService, that puts a new, anonymous principal in the AppDomain when it starts. The service is also responsible for negotiating authentication with a username and password taken from the user. To that end, and since the service is unable to ask for credentials to the client, it declares an ExtensionPort where modules can be plugged. When asked to EnsureUserIsAuthenticated, the services loops through the extenders plugged into its extension port, and asks them to NegociateAuthentication, passing the current (anonymous) SecurePrincipal object. Note that the extenders could have taken it from the current thread, since a module always runs in the application's AppDomain. The extender is responsible to get a username and password, usually by popping a window at the user, and to negotiate authentication, usually by calling a service that runs on the server. The first extender that successfully negotiates authentication wins, and the service stops looping. Latter, if EnsureUserIsAuthenticated is called again, the service simply returns (no window will be popped up, since to Extender will be called).
As you know, a Principal as an associated Identity object. For the same reasons, I created a SecureIdentity, and put a Promote method on it. The Identity holds the username and the authentication method and determines if the user is authenticated. To that end, I copied the behavior of GenericIdentity, which checks if the username is empty; if not then the user is considered authenticated. The Promote method takes a username and authentication method so that the user can go from anonymous (unauthenticated) to authenticated.
Since talking to a server generally means to exchange authentication tokens to prove one's identity on each call, and since one of the easiest ways to do that is to include the user's password on each request following authentication, I decided to add the Password property to SecureIdentity. That password, of course, is a SecureString, managed by the Window's kernel. Logically, Promote also takes that password for user's promotion. One can then get the current user's password from System.Threading.Thread.CurrentPrincipal.Identity, given that the authentication has successfully been negotiated.
With WCF and Message Credentials security (the preferred way to communicate over the Internet, according to Juval Lowy), you have to pass username and password with every request. Since Foundation uses an Object Container to abstract services, I don't want the consumer of a WCF service whose proxy is put into the Object Container to have to know that this service implementation is in fact a WCF proxy that asks for a username and password; therefore, my next step will be to create a reusable facade whose responsibility will be to intercept the consumer's call and put the username and password just before WCF marshals the call on the wire, using the Secure Principal and Identity of the current thread. Everything will be transparent to the user, Montreal Canadians will win the cup, and everybody will be happy ;-)
Framework makers often tend to dream of a software that can be configured in a time t lower then the time t' needed to build a solution from scratch using common 3GL tools and libraries in order to realize targeted business needs.
No software can be configured so that the cost of making it work is lower than the cost of 3GL. Corollary, any framework should only exist to serve as a guideline and guidance to good development practices, instead of trying to be a Software that builds Software. That's the essence of Omniscient's Foundation.
Lately I came across an interesting problem in WCF. It’s about generic contract types.
Before diving into this and presenting the solution, let me expose a little architectural problem as an introduction: The interface IEntityAdapter<TEntity>, in Omniscient.Foundation.Data is used in the business layer to save and load entities. It’s generally used in conjunction with IEntityController<TEntity> that helps manage the entity status, but can also be used directly. In a client-server implementation scenario, the adapter could stay on the server, while the consumer is on the client. Suppose we’re using WCF to communicate. Do we expose IEntityAdapter as a service contract, or do we hide it behind a façade, or another layer? What’s important here is separation of concerns. Should that interface be concerned by communication matters? Strictly speaking, the answer would be no. But when you consider it, an interface is already a contract; it’s a run-time contract, it helps us achieve dependency injection, inversion of control and unit testing. It defines the communication between two objects. So, why not extend it to be a WCF contract? Contract for contract, it’s pretty much the same concern!
The fact is that this interface is bridging the database. It’s a data layer interface, and its role is to define the interaction with the database. One lesson learned over time is that it’s dangerous to couple presentation layers with data stuff. You jump over the business layer, short-circuiting things like validation and business triggers. The result is that you end up putting business logic into the UI. Now, what’s a WCF service if not a presentation layer? It’s not inside a workflow, it’s at the beginning of a workflow; inputs from the “user” trigger business actions and therefore, it’s no different then every presentation layer. It even has its own user interface, the WSDL. Isn’t it logic then to try and separate WCF front-end from the back-end and IEntityAdapter?
When you’re building a framework you’re constantly facing this kind of question: how far should the framework go in order to protect the user (in the case of a framework, the user is always a programmer) against their own dumbness? Should I force the user into creating a façade over IEntityAdapter by omitting to decore it with WCF attributes? In my opinion, the answer is no. The developer is an intelligent creature; let them use your framework the way they want. Most frameworks out there are good at that: forcing you into a single, often complicated way of using it. Then, instead of helping you code better and faster, it’s often leading you into obscure and complicated paths where you can’t jump the fence. Is there a possibility that people would want to use IEntityAdapter as a service contract? Yes. Therefore, I decided to implement this behaviour into IEntityAdapter<TEntity>.
So! There begins the problem. At first, I decorated the interface with the required Contract Operation attributes, but it wasn't working (that's because of a configuration problem - more on that latter). Then I got interested into the fact that IEntityAdapter is a generic interface. You'll see that in this case it's not a problem, but I thought it was because I knew that the WSDL is unable to deal with generics (nor is it able to publish overloaded methods, by the way). Simply put, there's no way in WSDL to pass a type from the client to the server, to "feed" generic type parameters.
Here we must understand what I'm talking about: there's a difference between generics that are "instanciated" (whose real type is known at compile-time), and those that are still "open". It's the second type that cause us problems.
Let's present this with an example: Suppose I have the contract IContract, as below:
[ServiceContract()]
public interface IContract<T>
{
[OperationContract()]
T Echo(T item);
}
This contract can be easily published by WSDL, since the service itself (the class that implements the service contract) is not generic; by implementing the interface, it must specify the actual type of the generic type parameter, and in turn, the whole non-generic type is used in the endpoint contract. For example, if I have:
public class Service: IContract<string>
{
string Echo(string item)
{
return item;
}
}
then the endpoint's contract must be declared as follow: contract="IContract`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]". The reason why we use the assembly-qualified name of the type string is because that's the way it works in .net; generic type instances must be assembly-qualified in order to be valid (which makes total sense when you think about it).
That's working because WSDL has something to work with; the type of the contract is no longer IContract<T>, it's now IContract<string>.
Now, consider that little modification:
[ServiceContract()]
public interface IContract<T>
{
[OperationContract()]
T Echo(T item);
[OperationContract()]
T2 Echo2<T2>(T2 item);
}
Bang! That's not working. Why? Because "T2" is an "open generic"; it's still available to be changed at run-time! That's exactly the kind of things the WSDL is unable to represent. It's unable, in fact, to transfer the type parameter from the client to the server. Indeed, from the client, if you want to call this operation, you have to specify a type; and this type must make it to the server. WSDL and SOAP are unable to do that. When you try to open a host with a service implementing such contract, you get this error:
Type 'T2' cannot be exported as a schema type because it is an open generic type. You can only export a generic type if all its generic parameter types are actual types.
In fact, .NET is telling you that the WSDL is unable to 1-publish type parameters and 2-transfer type parameters from the client to the server.
Will this limitation be fixed in the future? I don't know...