Showing posts with label Software. Show all posts
Showing posts with label Software. Show all posts

Asp.Net MVC Dynamic Assembly Resolve

Background

In my scenario, I required 3 things for my application system (in fact, only the first one is mandatory):
  1. A set of library (framework) in which can be referenced by other applications
  2. Updating the version of the library to know deployment strategy or bug discovery. This means that minor, macro and micro version are updated regularly between publishing.
  3. The updated library should apply to all deployed systems
Up until now, in order to accomplish those three requirements, I had spent around 10 - 16 worth of working hours. A little waste I say. And to be honest, I still do not get the correct way to fulfill my needs.
The difficulty here in fact is the complexity of referencing the assembly, black box process of assembly resolving and inconsistency in application to resolve the assembly. Fortunately (and also unfortunately), this assembly complexity is only happen in web application (Asp.Net), and not winform (don't know about WPF though).
So what are the ways to resolve assembly that I had discovered up until now? N.B: the cons I stated below may be caused by insufficient of my knowledge and experience.

AppDomain.AssemblyResolve

One of the very first solution that I think will perfectly match my need is registering the AppDomain.AssemblyResolve event to reference the correct directory. It has some benefits:
  • You don't need to state assembly version. You just need to state the public key token and assembly name.
  • You can specify the location of the library.
  • Unlike GAC, no installation required for the shared library. You just need to dump the file in the folder.
  • The logic to resolve the assembly can be tracked by code, making debugging easier and new developer can know the assembly library location from code.
It really beneficial. You don't need any more effort in order to deploy a new installation, and the library can be separated from physical operating system. Moreover the version can be ignored, meaning that if you consistent in deploying only one version of library, then you are good.
However it also has several cons:
  • Intermittently the dll file can be copied into bin folder, rendering update useless.
  • Razor view engine does not call AppDomain.AssemblyResolve to resolving the assembly.
  • Web config compliation assembly reference don't call AppDomain.AssemblyResolve.
  • It must be signed with strong name.
  • Not consistent. Assembly update trigger cannot be determined.
Both of the cons make this solution cannot fulfill my needs, because I need every new deployment with updated version to be applied in all application. However even though if I can hack the version (not updating the assembly version), I still cannot overcome the second cons, that the assembly reference by razor view engine.

Installing the Assembly in GAC

Well, let's go to the point here, the benefit of using GAC:
  • Many experienced developer know how to use the GAC (it is standard).
  • It can be referenced by razor view engine.
  • The reference resolve is faster (not a big deal though).
  • It is consistent. The assembly update is triggered and can be known.
Then, what is the cons?
  • Assembly version need to be specified.
  • It needs to be installed with gacutil or predefined installer (not a big deal though).
  • The GAC location is locked and cannot be changed.
  • It must be signed with strong name.
Well, despite of it's cons, this solution can be used to meet my needs though. I just need to prevent the assembly version to be updated, and just updating only the file version. Multiple version assembly can also be used with this way to prevent breaking change, but my experience say that multiple version assembly can lead to headache at debugging.
I have yet not trying to use assembly policy things though. However it will still a bothersome to create a binding redirect policy for every assembly increment though.

Copying dll at Application_Start global.asax

Well, I found this solution to be interesting if it can be applied, because of these benefits:
  • The assembly does not need to be signed.
  • The directory can be specified.
  • The logic can be tracked by code.
  • It can be referenced by razor view engine.
  • The version does not need to be specified.
Then what is the cons?
  • Huge performance impact.
  • I still cannot get the correct logic to validate the flag to copy or not copy the dll, forcing the app to be compiled every request and rendering inproc session useless.
  • Not consistent. Assembly update trigger cannot be determined.
Ehem, the unstable and huge impact in performance makes this solution not implementable. Even though it has several benefits.

Copy dll Every Publishing

I had not yet trying this approach yet. This approach will use a custom tool to deploy the assembly to any registered applications. This approach has several benefits:

  • The base repository of dll can be specified. Does not need to use system location.
  • It can be referenced by razor view engine as well as compile assembly at web config.
  • It is consistent. The assembly update is triggered and can be known.
  • The assembly version does not need to be specified.
  • Does not need to be signed.
  • The manual copy dll via ftp can also be used to hosted application.
The cons:
  • Needs extra effort to make the tools for publishing. Do it manually and you will find yourself spending too much time.
  • The deployment can break due to several reasons, such as access limitation or file is locked.
  • You need to maintain the references.
Um well, this solution need a bit effort to establish. But it is possible. Moreover, I think that manual copy dll can also be used at hosted application.

Conlcusion

Well, I cannot make any conclusion here. I still do many experiment to solve this issue though. Up until now, copy dll every deployment is the best solution so far. It has several benefit and it can leverage the benefit from existing established automatic deployment. The solution is followed by installing GAC at the second place, with custom tool to automate generate assembly policy and install it in GAC.

The Ways of Debugging Part 1: Finding the Possible Root Cause

Background

Debugging can be easy for someone, and very hard for the other. After many years of debugging experience, I find that debugging usually consist of 3 big steps, that is:
  1. Finding the possible root cause,
  2. Prove the possible root cause to find the real root cause, and
  3. Fix the real root cause
Additionally, debugging hardware has many similarity with debugging software, in which also has the 3 big steps above.

Finding the Root Cause

Finding the root cause is the very first step in debugging. In my opinion, it is also the most determining step. The total time required for debugging usually be heavily determined by finding the root cause. It is harder to find the root cause rather than fix the system.

In order to find the root cause, the very first requirement is to understand the system you are debugging. I have once need to debug a system in which I do not understand at all, and it takes the time for me to understand the behavior of system first. Only after that then I can finally continue to find the possible root cause.

Moreover, don't be surprised. Sometimes user will actually submit a bug, without steps to reproduce (especially in entrepreneur system, where the user usually know little of software engineering), complaining about a behavior that is already behave as designed. Without any documentation (that's right, no documentation at all!) about how the system behave, I need to find a person who know the system's behavior, to determine whether it is a bug or not. This is, why at most of the time, usually the tester can find the possible root cause easily, because they know well how the system behave.

Understanding the system first can also be very critical for finding some technical flaws. There flaws are such as race conditions, replication issues, different regional setting, different input format, hacks or security flaws, etc. Right, bad system design can be a root cause for bugs, with additional factor like not understanding the system, it will give you a headache.

Another requirement for finding the root cause is having decent technical knowledge about the platform or programming platform the system use. Some platform used by the system such as the database and application, usually has different behavior between each other. Say, for example, java mark the class and method as virtual by default, and in C# you need to specify with the "virtual" keyword.

Conclusion

Understanding the system and having knowledge about the platform will give you significant boost in time needed to find the possible root cause. I have experienced that I have once finding a possible root cause for a bug in system for only several minutes. It is, of course are made possible by the having knowledge of the system.

Much or less, documentation about how the system behave will help newcomers or debugger to find the possible root cause. Not only it will help to find the possible root cause, the handler can instantly know whether the bug raised by user is actually the system's design or not, or they need to configure something in for the user in order to able to do the required action.

CUtility, Custom Component for C#

Sepertinya sudah setahun sejak pertama kali mengembangkan CUtility ini. Akhirnya diputuskan untuk dipublikasikan agar lebih banyak programmer yang dapat menggunakannya.

CUtility adalah custom library yang didesain untuk .Net, dibuat dengan bahasa C#. Isi dari CUtility sendiri bermacam-macam, mulai dari control UI yang dimodifikasi sendiri agar lebih mudah dan menarik, config-config yang lebih mudah digunakan dan semacamnya.
CUtility juga dilengkapi dengan CUtility.Print yang mendukung print dengan .Net Framework. CUtility.Print mendukung pencetakan table, pencetakan secara modular, pencetakan dengan metode-metode umum, dsb.
CUtility ver. 1.0.1.1. dapat didownload di sini.

Older version:
CUtility ver. 1.0.0. dapat didownload di sini.