0 Comments

A colleague of mine was having a problem with this issue yesterday.

If you are passing a URL with its own complex query string  in an HREF tag to a popup (window.open / showModalDialog, etc.), remember to do this:

<a href=”#” onclick=”window.open('foo.aspx?id=1&url=bar.aspx%3fvar1%3dONE%26var2%3dTWO')”>click me</a>

instead of

<a href=”window.open('foo.aspx?id=1&url=bar.aspx%3fvar1%3dONE%26var2%3dTWO')”>click me</a>

In the example above, I am trying to pass url “bar.aspx?var1=ONE&var2=TWO” tofoo.aspx when the popup window is opened.

There seems to be something about how the href tag is handled that when you do the method below (passing window.open...) inside the href tag, you will be guaranteed to lose var2=TWO

Give it a try.  It's weird, but interesting to know nonetheless.

0 Comments

I work in an intranet team that develop customized solution for my current company, its parent company and its subsidiaries. Needless to say, most of the time we found that we need similar domain objects such as Projects, Tenders, Contracts, Users / Employees, etc. across multiple application development projects. Of course, one thing that comes to mind is "Hmm... it would be great if we can pull all of these common domain objects from a single source to avoid duplication."

But... wait, it's not as simple as that.

Each application might not be used across all of the intranets. For example, application 1 is being built for subsidiary A, application 2 is being built for subsidiary B. The companies sometime are not even in the same country.

The easy way out: why the heck bother with a single source, just let each application has its own domain objects, even if it is similar in nature (application 1 has its own project domain, application 2 has its own project domain, etc.). Completely independent of each other. Nothing wrong with that, right?

Until... subsidiary B has a chance to look at the ...say... Leave Request application that is being used at subsidiary A and decided they want to use it too, but with some modifications to fit its own requirements. *Smack head* DOH... now what... well, again going with the simplest solution / hack that comes to mind... let's separate the database, tweak the application a bit, save it as LeaveRequestSubsidaryB, and there you have it. Nothing wrong with that, right?

Until... parent company (enterprise level) decided that all of these data should be integrated to make such and such big report / KPI on employee attendance or blah blah blah. You get the idea... Now what? *Scratch head* Uhm... create a common data container for all the different LeaveRequestXXX application, extract data from each of these apps and produce report on the common data? Well, that's one way to go. I am sure there are others.

The point of this long winding rambling is, well, this common data thing is bugging me. It keeps popping up no matter what. Why don't we just create one that can be shared across the enterprise? But, do we even have the time to do this first? We will certainly have to take into account all of the complexities of requirements from different applications and design it appropriately. That takes time. A LOT OF TIME.

Meanwhile, management keep asking when is application A going to be completed? What about application B, and so on... push push push ***ARRGHH! head is about to explode***

How can we move along different projects without having to wait for this "common domain object library" to be finished first?

Well... I gave this some thought and this is far from perfect, but here they are anyhow:

  1. Dependency Inversion comes to mind. What if we can find some common interfaces for these common objects and code against that the interface instead for common functions.
  2. Plug-in framework comes to mind. Replaceable domain object assembly that will allow each project to move along independently even without the common library to be completed.
  3. Extensible domain object through inheritance / company specific domain interface

Well, playing around with the idea, I managed to build a working prototype of point 1 and 2 so far. The hard part is designing the real interfaces. What are going to be the abstracted methods for such interfaces? I am starting with the simplest stuffs for now, for example, getting a list of Project to populate a dropdown list / lookup. That should be common enough across multiple application. There will be other more specific methods, but enough for now.

So, what do you think? Is such thing achievable? Or should we just give up on it and go w/ separate app for separate subsidiary, and reconsolidate the data when necessary?

0 Comments

What's the best practice on interface placement?

I was playing around with this idea after seeing an episode of DNRTV and thought it might be nice to just put this up in the blog and ask others' opinions on this subject.

For now, I can only think of 3 possible options for this issue.  And they are as follow:

Option 1.
Where: Place them in the assembly where the interface is implemented
When:

  • You should use this if you have all of your code inside a single assembly
  • You should use this when the majority of the time the interface is being used by derived classes in the same assembly

Some possible motives: 

  •   simple deployment (hey it's only a single dll)
  •   trying to implement some sort of design pattern / abstraction   (for example: plugin framework)

Example: I have an ILogWriter that is being used internally and my application configuration has a section in it where I can choose which kind of logging mechanism to use.

//Assembly : Foo.exe
//File     : ILogWriter.cs
namespace Foo
{
    public interface ILogWriter
    {
        void Write(string text);
    }
} 
//Assembly : Foo.exe
//File     : ConsoleLogWriter
namespace Foo
{
    public ConsoleLogWriter : ILogWriter
    {
        public void Write(string text)
        {
            Console.WriteLine(text);
        }
    }
}
//Assembly : Foo.exe
//File     : FileLogWriter
using System.IO; 

namespace Foo
{
    public FileLogWriter : ILogWriter
    {
        public void Write(string text)
        {
            //append text to file here
        }
    }
} 

//Assembly : Foo.exe
//File     : Class1.cs
using System;
using System.Configuration; 

namespace Foo
{
    public Class1
    {
        public void Main(string[] args)
        {
             // Do something
             ILogWriter logWriter = (ILogWriter)
             Activator.CreateInstance(Type.GetType(ConfigurationSettings.AppSettings["LogWriter"]));
        }
    }
} 

<!-- File : app.config -->
<appSettings>
    <add value="Foo.ConsoleLogWriter, Foo" key="LogWriter" />
</appSettings> 

Option 2.
Where: Place them in the assembly where the interface is being used
When:

  • You should use this one when the interface is only being used by that one assembly and  any other assembly using that interface will actually use the hosting assembly.

Some possible motives :

  • to only reference assembly that you are actually using.

Example: I have an IViewUserView in my presentation layer assembly and my actual view implementation will reference the presentation layer assembly since its going to use it anyway.

//Assembly : Blah.Presenter.dll
//File     : IViewUserView.cs
namespace Blah.Presenter
{
    public interface IViewUserView
    {
        int UserID { get; }
        string Login { set; }
        string Password { set; }
        // More here ...
    }
}
//Assembly : Blah.Presenter.dll
//File     : ViewUserPresenter.cs
using Blah.DTO;
using Blah.Task; 

namespace Blah.Presenter
{
    public class ViewUserPresenter
    {
        private IViewUserView view;
        private IUserTask task;
        public ViewUserPresenter(IViewUserView view) : this(view, new UserTask());
        public ViewUserPresenter(IViewUserView view, IUserTask task)
        {
            this.view = view;
            this.task = task;
        }
        public DisplayUser()
        {
            IUserDTO userDTO = task.GetUserById(view.UserId);
            view.Login = userDTO.Login;
            view.Password = userDTO.Password;
            // More here ...
        }
    }
} 

Option 3.
Where: Place them in their own assembly (assembly of just interfaces)
When: You should use this one when the interface is used by more than one assembly
Some posible motives :

  • reduce unnecessary references (you now only have to reference a single dll instead of multiples for different interfaces)
  • you want to separate implementations in different projects
  • trying to implement some sort of design pattern / abstraction (for example: extensible plugin framework)

Example: I have an IUserDTO (Data Transfer Object) that is being used by 2 other assemblies (Blah.Task and Blah.Presenter). Then it makes sense to put it into another interface specific assembly (Blah.Core).

//Assembly : Blah.Core.dll
//File     : IUserDTO.cs
namespace Blah.DTO
{
    public interface IUserDTO
    {
        string Login { get; set; }
        string Password { get; set; }
        // More here ...
    }
}
//Assembly : Blah.Core.dll
//File     : IUserTask.cs
namespace Blah.Task
{
    public interface IUserTask
    {
        bool Login(IUserDTO userDTO);
        // More here ...
    }
} 
//Assembly : Blah.Core.dll
//File     : IViewUserView.cs
namespace Blah.View
{
    public interface IViewUserView
    {
        int UserID { get; }
        string Login { set; }
        string Password { set; }
        // More here ...
    }
} 
//Assembly : Blah.Task.dll
//File     : SecurityTask.cs
//Reference: Blah.Core.dll for the IUserDTO interface
//    ...
using Blah.DTO;
using Blah.Task;
using Blah.DataAccess; 

namespace Blah.Task
{
    public class SecurityTask : ISecurityTask
    {
        public bool Login(IUserDTO userDTO)
        {
            return SecurityDataAccess.Instance.Login(userDTO.Login, userDTO.Password);
        }
    }
} 
//Assembly : Blah.Presenter.dll
//File     : ViewUserPresenter.cs
//Reference: Blah.Core.dll for the IUserDTO, IViewUserView and IUserTask interfaces
//    ...
using Blah.DTO;
using Blah.Task;
using Blah.View; 

namespace Blah.Presenter
{
    public class ViewUserPresenter
    {
        private IViewUserView view;
        private IUserTask task;
        public ViewUserPresenter(IViewUserView view) : this(view, new UserTask());
        public ViewUserPresenter(IViewUserView view, IUserTask task)
        {
            this.view = view;
            this.task = task;
        }
        public DisplayUser()
        {
            IUserDTO userDTO = task.GetUserById(view.UserId);
            view.Login = userDTO.Login;
            view.Password = userDTO.Password;
            // More here ...
        }
    }
}

These examples and options are just what were on my mind when I wrote this post and not to be taken as a real guideline for interface placing.  If anyone should know a better way to do this, by all mean, please share them.

0 Comments

Coming back from the Architect Forum session on last Friday, I decided to play around with WinFX a little.
I decided to install these on a Windows Server 2003 SP 1 machine.

Some road blocks that have to be cleared:

  1. Visual Studio 2005 Orca and Workflow extension ... These two are not so bad of a download.  It's better to clear these two first.
  2. WinFX runtime... Ugh... I hope you have enough bandwidth and connection time... At first sight, it only requires a 2 MB download, but... that's just the installer to download the rest of the runtime (which is about 50mb) from the web.  To complicate things, I was behind a proxy that requires authentication, blah blah blah. Never mind that, in the end, I decided to be brave (I hope this is not turning out to be a stupid decision that I'll regret later on, but... we'll see) and installed it on my workstation that's already joined to the domain and configured correctly to connect to the download site.
  3. Windows SDK... double Ugh... Boy, if you have enough bandwidth and connection time for the previous download, I really really hope you have enough bandwidth and connection time for this big boy.  1+ Gigabytes of data to download.  Yeah!! Woohoo!! (Jump around with joy...NOT).  Well, be prepared to camp your computer 1 or 2 or 3 or 4 or ...(you got the idea) more days to download this big ... (fill in the blank) of an SDK.  Uhm... if you are doing Vista February CTP, I think you have to download a different Windows SDK version.  I recalled seeing a download for this from MSDN Subscription site.  I am not sure.  Someone correct me if I am wrong.
  4. Go grab some WinFX examples from the web (there are hands on lab and what not from MSDN site).

After all the downloads fun and joy... It's time for installation.

To save you pain and suffering I suggest you read the installation instruction... Uhm..it's somewhere on MSDN WinFX site I think... forgot where.. go dig around...

But if you are too lazy to go browse around, here is what worked for me:

  1. Install Visual Studio 2005 (Express will do)
  2. Remove .NET Compact Framework 2.0 installation if it's installed from Add / Remove Program
  3. Install Windows SDK (If you didn't do step 2, the installation will stop)
  4. Install Orca extension
  5. Install Workflow extension
  6. Install any samples that you might want to play around with.
  7. Install XamlMigrate (hmm..forgot the link, go Google it), apparently most of the samples are older ones that will not compile correctly without this tool.  To use XamlMigrate, go read the readme file that comes w/ it.
  8. Have fun.

Now... anyone know where I can get that cool rotating photo browser demo that was shown in the SAF event last time?  Nudge 2x Wink 2x.... :)