Abstract form

Mutually Dependent Systems

Posted in Architecture, Development, Modeling by Homam Hosseini on March 11, 2010

In this post I am discussing a problem that I have faced several times in the past year. Simplicity is always a goal in design as it saves resources during development and maintenance. But it’s not always clear which design is simpler. Sometimes a seemingly complex design turns out to be simpler to develop, maintain and extend.

In a master-slave architecture, assume S1 is the master. It produces one or more tasks form a given job and transfers them to S2 (the slave); S2 does the tasks and return the results back to S1. S2, the slave, depends on S1, the master.

If the next time that S1 assigns a task to S2 it uses the information that exists in the result of a previous task that had been assigned to S2 then S1 also depends on S2 and we have a mutually dependent couple.

In our terminology the systems are mutually dependent if and only if S1 uses the information it gained as a result of a previous task that it had already assigned to S2. It doesn’t matter if S2 has completed the previous task or not, but it should have reported something to S1 that is useful for S1 for a next assignment of a task to S2.

If S1 is only using the fact that S2 is busy or free then we don’t call it a mutual dependency. S1 must use the information that is generated by processing a task at S2. For example a MapReduce system is not a mutually dependent system.

Why is it important? You should have already guessed that S2 is the name of a class of slave systems that work with S1. There could be many instances of S2. Let’s define a homogenous mutually dependent system as a system that in which all slaves of S1 are in the same class.

Two slaves are of the same class if they share a common interface for communicating with S1.

Now assume that S3 is also a slave for S1. S3 is in a different class other than S2 if either its input or its output interface is different from S2’s.

When designing mutual dependent systems we have to always decide whether to keep the mutual dependencies or to break them by introducing new nodes. It’s mainly a decision over complexity. The other factor that may affect your decision is the swiftness of the system. Introducing a new node will usually reduce the responsiveness.

Breaking the mutual dependency by using S4 node. Note that S3 is another class and uses a different interface to communicate with S4.

For instance a new node must not be added if S1 waits for S2 to return. Generally you should try to keep the number of nodes as small as possible if the operations are not asynchronous.

Homogenous mutual dependency is OK (when the systems are simple and synchronous) but things get much dirtier as we introduce new classes to the system. On the other hand if extensibility is a goal you should try to avoid mutual dependencies.

For a conclusion, use mutual dependent systems in live systems, when a rapid response is required, and try to avoid them by introducing middle nodes if you have many classes of slaves or if extensibility is a goal.

Advertisements

iframe Cookies in Safari

Posted in Coding, Development by Homam Hosseini on February 10, 2010

Older Hyzonia games depend on session and authentication cookies. This dependency has been fixed in the newer games by storing session ID in JavaScript variables. The cookie independent services explicitly require a session ID to be sent by their clients.

In this post I am not going to dig into the details of session management in Hyzonia platform, I just want to highlight a series of problems in the old schema that led us to redesign the session management behavior.

Hyzonia games can be embedded in publishers websites using a piece of code we call Hyzobox. Hyzobox basically renders an iframe in the webpage. The internet domain where the actual game is hosted could be different from the publisher’s domain. If you have ever tried this before you know that we gonna have a lot of cross site security issues.

To address cross site scripting issues we developed Hyzobox In/Out API. A publisher can control certain things in the game and be notified about the events that are occurring inside the game using In/Out. It is a JavaScript based solution and strangely is widely supported in all major browsers. The In/Out API is not made public yet, but we are using it extensively in www.hyzogames.com. For instance whenever you win in a game Hyzogames.com will be notified about this event (winning) and may show you a message box.

But cookies are another issue. Different browsers have way different behaviors when it comes to handling cookies in iframes.  For starters for it  to works in IE you need a P3P header like this:

CP=”IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT”

There’s a lot to say here, I have a long standing view that P3P is generally useful but this kind of usage is pointless. Anyway for now just add it in your response and relax.

But still Safari rejects the cookies that iframes try to write. The rationale here is that Safari only wants to write cookies from websites that the user directly visits. It’s not a bad idea for privacy. Let’s assume that you are visiting a fan website for The Grudge! thegrudgefans.com is using  Google AdSense  (put any evil multibillion dollar internet ad service instead of Google :D) to display you some ads or even just in the background. The AdSense is running inside an iframe and it writes a cookie on your computer indicating you’re a fan of nonsense horror teen movies. Now it is written on your face that you’re a fan of The Grudge. AdSense can use this cookie anywhere else in the internet. OK you got the idea.

The problem was this privacy feature in Safari was causing our Hyzobox User Integration (a kind of Single Sign On service) to break. Safari users can always turn on a checkbox in the preferences to accept all cookies. But it’s not the case by default. The workaround is that the page that writes the cookies must be initiated as a result of a direct user request. Literally meaning that prior to writing any cookie you have to provide a hyperlink (an explicit anchor tag) in your iframe that takes the user to the page that writes the cookie.

Tagged with: , , , ,

Hollywood Principle

Posted in Coding, Development, Internet, JavaScript by Homam Hosseini on December 7, 2009

Today I was working on refactoring some names in Hyzobox In/Out API. It is my personal favorite piece of code in the whole platform. In summary it allows the publisher of the game to customize the game in runtime dynamically by injecting codes and executing some functions in the context of the game (In) and to get notified about the events that are occurring inside the game (Out).

Inversion of Control is very natural in JavaScript and it has been used extensively in In/Out API. It’s quite different from popular prototype pattern but most everyday JavaScript programmers use IoC even though they don’t usually notice it.

Here is a sample in our API:

We register an event listener in Hyzobox, waiting for landing view of the game to be loaded:

var hb = Hyzobox.createInstance();
var landingview_loaded = function(hbEvent) {
   // do something with hbEvent
}
hb.addEventListener('landingview_loaded', landingview_loaded);

It’s is clear that we don’t have control over when landingview_loaded event will be fired and its handler will be called.

hbEvent argument that is of type Hyzobox.Event has a data attribute that is of type Object. In this example the data is a LandingView instance. We can interact with this object in the event handler:

var landingview_loaded = function(hbEvent) {
   var view = hbEvent.data;
   view.inject('a-container-id', 'some text');
};

In this example we are injecting ‘some text’ to an element identified by ‘a-container-id’ inside landing view.

addEventListener() is part of Out and inject() is part of In API. If we want to listen to the events that are occurring inside a particular view, we should register their halnders after the view has been loaded:

var landingview_loaded = function(hbEvent) {
   var view = hbEvent.data;
   view.attachEventListener('playNow', function playNowHandler(playNowHbEvent) {
       // do something with playNowHbEvent
   });
};

And so on, we can have many nested Ins and Outs.

It’s easy to see that in these examples the control has been transferred to the event handlers. The caller raise the events but it’s the responsibility of the handlers to control the functionalities.

I don’t want to go into the the details now, because the work hasn’t yet been finished on these APIs. Once released, we will post them in Hyzobox documentations and Hyzonia tech blog in the following weeks.

Tagged with: , , ,

Accessing Remote ASP.NET Web Services using JSONP

Posted in Coding, Development, JavaScript by Homam Hosseini on October 12, 2009

The problem:

You cannot call remote ASP.NET web service methods from a JavaScript, AJAX client.

Example:

You have a web service, at this address: http://a.com/service.asmx and you’ve configured the service to work with AJAX clients:

[WebService
(Namespace = "http://www.hyzonia.com/gametypes/PopNDropLikeGame/WS2")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class GameService : System.Web.Services.WebService
{
    [WebMethod(EnableSession = true)]
    public GameSessionResponse CreateGameSession(Guid questId)
    {
...
    }
}
}

And it works fine when you call its methods from a web page that is in this address: http://a.com/page.htm:

$.ajax({
        type: "POST",
        url: "GameService.asmx/CreateGameSession",
        data: "{questId: '" + questId + "'}",
        cache: false,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(response) {
            Game._onSessionGot(response.d);
        }
    });

But the very same client-side code doesn’t work from this address: http://b.clom/page.htm

The problem in depth:

At first I cannot hold myself and not say that it is a silly problem. web services are meant to be called by remote clients. The fact that browsers block access to web services by AJAX calls is clearly contrary to the purpose of web services.

Interestingly browser extensions like Flash and Silverlight also by default block remote web services, but they provide a work around. Unfortunately no browser by date supports this work around for XMLHTTPRequests. This “security measure” seems odder when we notice that it is perfectly correct to import a JavaScript code snippet from another domain by a script tag:

<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
type="text/javascript"></script>

 

The solution:

As it was said, Flash and Silverlight both support remote calls. You just need a clientaccesspolicy file to be hosted at the root of a.com (http://a.com/clientaccesspolicy.xml):

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

This file allows remote calls to be made from any other domain.

But in many situations we want to call the web service methods directly by AJAX clients. This need was the cause of to the development of JSONP (JSON with padding) protocol. As it was discussed it is correct to have a <script> element that loads a script from another domain. On the other hand you may know that it is possible to load scripts dynamically by a simple JavaScript trick (writing<script> tags) or using this jQuery plug in. Now the bulbs are flickering! The solution is to access the JSON web service by the src attribute of a <script> element. This is the whole idea behind JSONP.

But there are a couple of problems needed to be solved for ASP.NET ASMX web services before we can use them in a JSONP scenario.

  1. ASP.NET web services by default only accept POST requests, a <script src=””> element, produces a GET request.
  2. The result of the web method call must conform to JSONP, and you guess, ASP.NET 3.5 by default doesn’t support it.

The solution to the first problem may seem trivial, we can easily enable GET calls to web methods using [ScriptMethod(UseHttpGet = true)] attribute. The immediate problem is that when we mark a web method by this attribute it only can be called by GET requests. And remember, other clients (actually anything other than JSONP clients) are supposed to communicate with the web service by POST requests. I usually end up inheriting from the original web service and marking web methods by [ScriptMethod(UseHttpGet = true)] attribute in the derived class. Therefore I will have two ASMX web services, one using the original class (expecting POST request) and the other using the derived class (expecting GET requests).

[WebMethod(), ScriptMethod(UseHttpGet = true)]
public override GameSessionResponse CreateGameSession(Guid questId)
{
   return base.CreateGameSession(questId);
}

Note you may need to add this code snippet in web.config:

<system.web>
 <webServices>
   <protocols>
     <add name="HttpGet"/>
   </protocols>
 </webServices>
…
</system.web>

There’s another problem to be addressed in the client side. The client should call the web method by a correct URL (it has to pass a correct query string that could be deserialized back to .NET objects in the server side). In case of POST requests, I’m used to JSON2 library to post data to ASP.NET ASMX web services. Jquery $.AJAX method (when it is configured to use JSONP, by dataType: “jsonp”) creates query string parameters for the data object it receives. But the result is not usable for ASMX web services.

Luckily there’s a ready to use JQuery plug in (jMsAjax) that has the required algorithms for serializing a JavaScript object into a query string that can be parsed by ASP.NET web services.

Using the plug in I created this function to serialize JavaScript objects into query strings:

$.jmsajaxurl = function(options) {
    var url = options.url;
    url += "/" + options.method;
    if (options.data) {
       var data = ""; for (var i in options.data) {
       if (data != "")
         data += "&"; data += i + "=" + msJSON.stringify(options.data[i]);
       }
       url += "?" + data; data = null; options.data = "{}";
   }
   return url;
};

You will need jMsAjax for this code snippet to work.

Finally this is a sample of a client side code using JQuery that calls an ASMX web service using JSONP:

var url = $.jmsajaxurl({
    url: "http://hiddenobjects.hyzonia.com/services/GameService3.asmx",
    method: "Login",
    data: { email: "myemail@mydomain.com", password: "mypassword" }
});

$.ajax({
    cache: false,
    dataType: "jsonp",
    success: function(d) { console.log(d); },
    url: url + "&format=json"
});

Or equivalently:

$.getJSON(url + "&callback=?&format=json", function(data) {
    console.log(data);
});

When you call an ASP.NET web service method (that is configured to receive GET requests) using a code similar to the above, it returns in XML. The problem is that the web service expects to receive a request that has a content type of “application/json; charset=utf-8” and <script> element simply doesn’t add this content type to the request. There’s a little thing we can do at the client side. The easiest way to resolve this problem is to use a HTTP module. The HTTP module should add this content type to the requests before they are processed by the web service handler.

On the other hand a JSONP client expects that the web service return the call by a string like this:

nameOfACallBackFunction(JSON_OBJECT_WEB_METHOD_RETURNED)

nameOfACallBackFunction must be given to the server by a parameter in the query string. Different JSONP compatible web services use different names for this parameter, but usually it is named ‘callback’. At least this is what $.ajax() automatically adds to the request in JSONP mode.

I grabbed this HTTP module from a post in elegantcode.com.

public class JsonHttpModule : IHttpModule
{
    private const string JSON_CONTENT_TYPE = "application/json; charset=utf-8";

    #region IHttpModule Members
    public void Dispose()
    {
    }

    public void Init(HttpApplication app)
    {
        app.BeginRequest += OnBeginRequest;
        app.ReleaseRequestState += OnReleaseRequestState;
    }
    #endregion

    bool _Apply(HttpRequest request)
    {
        if (!request.Url.AbsolutePath.Contains(".asmx")) return false;
        if ("json" != request.QueryString.Get("format")) return false;
        return true;
    }

    public void OnBeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (!_Apply(app.Context.Request)) return;

        if (string.IsNullOrEmpty(app.Context.Request.ContentType))
        {
            app.Context.Request.ContentType = JSON_CONTENT_TYPE;
        }
    }

    public void OnReleaseRequestState(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (!_Apply(app.Context.Request)) return;

        app.Context.Response.Filter = new JsonResponseFilter(app.Context.Response.Filter, app.Context);
    }
}

public class JsonResponseFilter : Stream
{
    private readonly Stream _responseStream;
    private HttpContext _context;

    public JsonResponseFilter(Stream responseStream, HttpContext context)
    {
        _responseStream = responseStream;
        _context = context;
    }

    public override bool CanRead { get { return true; } }

    public override bool CanSeek { get { return true; } }

    public override bool CanWrite { get { return true; } }

    public override long Length { get { return 0; } }

    public override long Position { get; set; }

    public override void Write(byte[] buffer, int offset, int count)
    {
        var b1 = Encoding.UTF8.GetBytes(_context.Request.Params["callback"] + "(");
        _responseStream.Write(b1, 0, b1.Length);
        _responseStream.Write(buffer, offset, count);
        var b2 = Encoding.UTF8.GetBytes(");");
        _responseStream.Write(b2, 0, b2.Length);
    }

    public override void Close()
    {
        _responseStream.Close();
    }

    public override void Flush()
    {
        _responseStream.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _responseStream.Seek(offset, origin);
    }

    public override void SetLength(long length)
    {
        _responseStream.SetLength(length);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _responseStream.Read(buffer, offset, count);
    }
}

This HTTP module will be applied to each request to a .asmx file that has a format=json in its query string.

Note that you have to update web.config:

<system.web>
…
  <httpModules>
    …
    <add name="JSONAsmx"/>
  </httpModules>
</system.web>

For IIS6 and

<system.webServer>
  <modules>
  …
    <add name="JSONAsmx"/>
  </modules>
  …
</system.webServer>

For IIS7.

Now to test is open your web service in your browser, in my example:

http://hiddenobjects.hyzonia.com/services/GameService3.asmx/Login?email=e@e.com&password=p

It should return in XML

And

http://hiddenobjects.hyzonia.com/services/GameService3.asmx/Login?email=”e@e.com”&password=”p”&format=json&callback=myCallBackFunc

Will return:

myCallBackFunc({"d":{"__type":"HLoginResponse",
"isSuccessful":false,"error":false,"authSessionId":null,"nickName":null,"score":0}});

Don’t worry about myCallBackFunc, JQuery nicely manages it, so that the whole business is behind the scene and you can use $.ajax success callback the very same way you use it for a normal AJAX call.

We should note that JSONP has its own problems, especially… yes… in IE! All versions of Internet Explorer has a 2083 character limit for the URL of a request. It means that you cannot send large data in GET requests to the server. Sometime this limitation leaves us with no choice but to use Flash or create a proxy to the remote web service in the local domain.

Why make an advergame for Hyzonia?

Posted in Architecture, Business, Coding, Development, Internet by Homam Hosseini on August 14, 2009

We have been working on a few cool features of Hyzonia in the past weeks. Hyzonia is a next generation internet ad service. Like traditional ad services Hyzonia receives advertisements from advertisers and distribute them in websites. But the ad materials in Hyzonia are not in the form of traditional banner or text ads. The ads would be placed inside games, in a way that players would interact and engage with the promoted subjects. This kind of games is being called an advergame. I don’t want to dig into the marketing stuff, but it worths mentioning that one interesting feature of Hyzonia is that it makes it easier for advertisers to utilize the power of advergaming, for less, as Hyzonia is providing a rich set of ready-to-use advergames. Using Hyzonia customers do not need to pay big moneys to interactive software companies to make and host an advergame as part of their online campaign.

We already have built a number of  favorite games, but Hyzonia is extensible by nature, meaning that it is easy to create an advergame for Hyzonia or integrate an already built game into it. Like almost every big web business we know, we found it is crucial for Hyzonia to be extensible and customizable. Hence we spent the last few weeks on making final touches on the first version of our APIs, improving security and testing it all by making sample games.

It’s no myth that most succesful indie developers are game makers. If you have some good ideas, you may find your two-week project shining on the top lists in Xbox Live or Apple Store.

In comparison with those programs, in Hyzonia you will start earning from the moment your game is added in the system. It would be based on a revenue sharing model, so as long as your game is attractive for promoters there would be some campaigns active in some instances of your game and a revenue stream for you. On the other hand contrary to Miniclip or Pogo, Hyzonia is not a single game portal, your game eventually will be displayed in our publishers’ websites. Hyzonia is a service that provides the infrastructure needed for this communication among advertisers, publishers, and developers to happen.

Currently in addition of standard Web Service interfaces we are providing .NET libraries that encapsulate all the basic functionalities that an advergame in Hyzonia platform should support. One exciting news is that you don’t need to make everything from scratch using Hyzonia APIs, but the required functionalities of an advergame in Hyzonia have been designed in a way to make it possible to take virtually any game, wrap it inside a shell (we call Island) and have it added in Hyzonia. The .NET libraries that we are shipping as part of the API have all the functionalities needed by this shell.

Because of its service oriented architecture, Hyzonia advergames (Islands) could be anywhere in the internet. But currently we are only activating the games that have been hosted physically in our datacenters, although exactly like a banner ad (hosted let’s say by DoubleClick) they could be displayed on other websites.

Obviously not any game can be converted into an advergame. This is another issue that we are adderssing it in the guidelines that will be released alongside the APIs.

A thousand words: Hyzonia connects developers, advertisers and websites.

Returning Anonymous Types in Web Services

Posted in Coding, Development by Homam Hosseini on July 9, 2009

When coding an AJAX app that makes relatively many calls to the server in short periods of time, the main concern is to minimize the bandwidth it consumes. For example think of an AJAX chat application. For it to look like a real time app we have to query the server every few seconds.

If you’re using .NET, you already knew how easy it is to return objects and have them serialized in JSON in Web Services. All we need to do is to deal with the logics and .NET does all the things and tricks related to the communication. For our example, this is the method that needed to be called periodically from the client:

[WebMethod]

public IEnumerable<ChatMessage> GetMessages()

{

var currentPlayer = OnlinePlayers.Single(p => p.Id == CurrentPlayerId);

var messages = Messages.Where(m => m.DateSent > currentPlayer.DateSynced);

currentPlayer.DateSynced = DateTime.Now;

return messages;

}

The problem is that .NET really serializes everything. If we have the following definitions:

[Serializable]

public class Player

{

public Player() { }

public string Name { get; set; }

public string Id { get; set; }

public string PhotoUrl { get; set; }

public DateTime DateSynced { get; set; }

// other properties

}

[Serializable]

public class ChatMessage

{

public ChatMessage() { }

public Player Sender { get; set; }

public string Message { get; set; }

public DateTime DateSent { get; set; }

}

It is certainly not desirable to send a Player object back to the client by every ChatMessage. Assuming that the client already knows all the Players involved in the Chat, the ChatMessage object that is being sent to the client only needs to have a Sender ID property. One obvious solution that is very familiar for hardcore client-server developers is to have another type, let’s say ClientChatMessage that only contains the required information. If you’re taking this approach remember ClientChatMessage should be a struct type:

[WebMethod]

public IEnumerable<ClientChatMessage> GetMessages()

{

//…

return messages.Select(m => (ClientChatMessage)m);

}

[Serializable]

public struct ClientChatMessage

{

public string SenderId;

public DateTime DateSent;

public string Message;

public static explicit operator ClientChatMessage(ChatMessage m)

{

return new ClientChatMessage()

{

DateSent = m.DateSent,

Message = m.Message,

SenderId = m.Sender.Id

};

}

}

When we are targeting only AJAX clients it’s very handy to return anonymously typed objects. Anonymous objects cannot be serialized by XML serialization, but JavaScript (JSON) serializer is able to serialize them. I prefer it:

[WebMethod]

public IEnumerable<Object> GetMessages()

{

//…

return messages.Select(m =>

new {

s = m.Sender.Id,

m = m.Message,

d = m.DateSent

});

}

Here I’ve shortened the names of the properties, hey it is AJAX, we should save bandwidth by every mean possible.

We’ve used this trick in many places of the games we are developing for Hyzonia, as the current games only will be available for JavaScript clients. We found another similar trick very handy: a web method can take an object as an argument; if you send a JSON serialized object from the client to these methods, you’ll have a Dictionary<String, Object> in the server side.

[WebMethod]
public IEnumerable<ChatMessage> GetMessages()
{
var currentPlayer = OnlinePlayers.Single(p => p.Id == CurrentPlayerId);
var messages = Messages.Where(m => m.DateSent > currentPlayer.DateSynced);
currentPlayer.DateSynced = DateTime.Now;
return messages;
}

How to use cursors in web pages, painless

Posted in Coding, Development, Internet by Homam Hosseini on June 14, 2009

The shortcoming of current edition of HTML and the whole technologies we build the user interface of our websites on is no secret. Here is an example: If you want to put a custom cursor on an element use this markup:

element { cursor: url('pointer.cur'), default }

I know you may think custom cursors are not being supported in FireFox, but it’s not the case if you append a ‘, default’ (or any other standard CSS cursor value instead ‘default’).

If you are looking for a painless software to create mouse cursors, we fond AniTuner easy and useful. Don’t get it wrong it can be easily used to create static .cur files that can be displayed in major browsers.

Generally as a user experience point of view, it is not a good idea to have custom cursors  in web pages, but when you are developing an online game, a smart use of cursors can make it simply more attractive.

Service Provider Pattern Part II

Posted in Architecture, Coding, Development by Homam Hosseini on May 29, 2009

Read the first part

At first I found it is generally a good advice to store the configuration in a static, read-only property somewhere. And there’s no better place other than the configuraiton class itself:

static MyServicesConfigurationSection _Value;
public static MyServicesConfigurationSection GetValue()
{
   if (_Value == null)
   {
     _Value = (MyServicesConfigurationSection)
        System.Configuration.ConfigurationManager.GetSection("myServices");
   }
   return _Value;
}

Here we assume that we always define the matching element to be “myServices” in the configuration file. It makes sense because it makes it easier for us to find the element in different configuration files. We can always access the value using:

var config = Configuration.MyServicesConfigurationSection.GetValue();

Modularizing is the obvious upgrade we are goging to make to the Service Provider Pattern Part I. I can find three distinct components:

Service-Provider-Pattern-Ar 

  • Service Provider Pattern contains all the logic required by the pattern to work. You alway reference it everywhere you want to use the pattern.
  • Service Definitions is where we define our services.
  • Implementation of the Services contains  concrete classes and implementations of (some of) the services that have been defined in Service Definitions module. In a real application you may end up with many Implementation components each containing the implementation of a one or few number of services.

As before the configuration file of the Host Application maps the definitions (abstract services) to implementations (concrete services).

It’s clear that using this architecture we can have host applications that are hosting different implementations of the services.

Configuring the Services

Till now the only purpose of the configuration file was to store the mapping between the definitions and the implementations. But we can use it in order to actually configure the services. For an example it’s very likely that the FTPFileStorageService that we defined in the previous part, needs a FTP account credential to work. In this case the <add> element (that maps FileStorageService to FTPFileStorageService) may look like:

<add def="MyServiceDefinitions.FileStorageService"
     impl="MyServiceImplementations.FTPFileStorageService,
                                      MyServiceImplementations"
     host="ftp://ftp.wingooli.com" username="wingooloi"
                                         password="password" />

Both the abstract service definition and the concrete implementation can implement IServiceBase interface:

public interface IServiceBase
{
    void Initialize(Configuration.ServiceProviderSettings settings);
}

This interface just has one method, Initialize, that takes a ServiceProviderSettings (the <add> element). We can read the additional attributes of the <add> element using a code like this:

settings.Properties["host"]

The logics in the Service Provider Pattern component automatically call the Initialize method if this interface has been implemented in the definition the  implementation of the service.

Here is the design:

Service-Provider-Pattern

Now our Service Provider Pattern has nothing less than ASP.NET Provider Pattern but it is easier to implement.

Using all these modules we can reduce the code needed to instantiate a service (this code snippet should be placed in the abstract service definition class):

static FileStorageService _Instance;
static object _InstanceLocker = new object();
public static FileStorageService Instance
{
 get {
    if (_Instance == null) {
      lock (_InstanceLocker) {
        _Instance =  ServiceModel.ServicesHelper
                       .GetServiceInterface<FileStorageService>();
      }
    }
    return _Instance;
  }
}

Because it is a repeatable pattern and to make it all more developer friendly, I created a C# code snippet that generates a similar code automatically.

You can download the whole things here.

JQuery Auto Ellipsis Plugin

Posted in Coding, Development by Homam Hosseini on May 25, 2009

It is one of my most favorite JQuery plugins I coded for Dig and Win. As Dig and Win is a AJAX game, we have developed many JavaScript snippets including JQuery plugins and controls and behaviors for Microsoft AJAX Framework. And I had much fun working on JavaScript, honestly I didn’t know how powerful and how interesting this language is before working on the Dig and Win game. Check out Auto Ellipsis in my homepage or its JQuery page.

JQuery Wingooli Photo Gallery

Posted in Coding, Development, Internet by Homam Hosseini on May 10, 2009

I just want to introduce a JQuery photo gallery plugin I developed fro my profile. My main motivation for building this plugin was that I wanted it to be search engine friendly therefore I needed a clear separation between the photo gallery functionalists and the data describing the photos and the gallery. It is something that is easy to achieve using JQuery.

BTW these days I spend a part of my time discussing and teaching OOP JavaScript to our fellow programmers in RENA. It’s interesting for me to discuss the somewhat weird features of JavaScript for these guys who are already well experiencedand talented .NET developers. I try my best to convince them JavaScript is so fun when you get used to it, so fun and so powerful that you end up you want to kiss all the ASP.NET AJAX and UI functionalists a goodbye and develop the effects yourself and see how much you can improve the performance and the branding of your application.

We in RENA are looking for a Web UI Developer to handle such those tasks, it came out to be a very hard job finding a person for this position, mainly because it requires you to be a JavaScript God! to pass the first step in the recruitment process. Drop us a message if you fit the position.

Tagged with: ,