Sunday, April 21, 2024

OHIF Dicom Viewer & Orthanc Server

 Running Orthanc Server & OHIF DICOM Viewer

OHIF DICOM Viewer

A viewer is available here https://github.com/OHIF/Viewers and is fairly easy to build and configure. Requires node & yarn and little configuration (to be seen later)

Orthanc Server [on a different machine]

Orthanc Server can be found here https://orthanc.uclouvain.be/book/ and it has a number of plugins that you can configure. One of which is the DICOMWeb which is the plugin that implements the DICOM-Web standard. This is the one you need to enable in order for The OHIF Viewer to work with Orthanc. Orthanc has its own RESTful API but it's the same API that OHIF Viewer uses.

CORS

Orthanc Server and it's DICOMWeb Plugin should ideally behind a reverse-proxy/load-balancer. This allows to set the necessary headers to allow scripts in one domain to call the DICOM API.

Here is an example NGINX Configuration

server {
    listen 8042;
    server_name localhost;

    location / {
        proxy_pass http://your_orthanc_server_ip_address_or_hostname:8042;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;

        proxy_set_header X-Test-Id 'some_value';
        add_header Access-Control-Allow-Origin 'http://localhost:3000';

    }
}

 Assuming your OHIF Viewer is running on http://localhost:3000

Don't forget to configure your plugin DICOMWeb Plugin of the Orthanc Server so that the Host value is the proper one it should be whatever your reverse proxy is otherwise; you'll run into weird CORS and/or connection errors.

Just some configs that helped me. Hopefully this helps.


Sunday, September 5, 2021

Building OpenWRT

 Compile OpenWRT Locally

If you're following the commands here https://openwrt.org/docs/guide-developer/build-system/use-buildsystem, specifically

# Download and update the sources
git clone https://git.openwrt.org/openwrt/openwrt.git openwrt
cd openwrt
git pull
 
# Select a specific code revision
git branch -a
git tag
git checkout v19.07.8
 
# Update the feeds
./scripts/feeds update -a
./scripts/feeds install -a
 
# Configure the firmware image and the kernel
make menuconfig
make kernel_menuconfig
 
# Build the firmware image
make -j $(nproc) defconfig download clean world

And finding out that the ./scripts/update -a fails because the which dependency isn't found then the solution is to temporarily remove the which alias.

Which is a very common GNU utility that tells you where a certain command is (on the filesystem or as an alias). On my Linux installation the which command is wrapped within an alias. 

  • Remove it temporarily in a number of ways: you can go to /etc/profile.d/ and rename the which2.sh (or which2.csh depending on which shell you're using) to something that does not end in .sh. 
  • Close the current terminal/session
  • Start a new terminal and run which which and verify that you're getting the path of the which utility and not the alias
  • Re-run the build steps
  • Restore the which alias

 

Saturday, March 20, 2021

Installing ElasticSearch on Dev Kubernetes

 Installing Kubernetes

I used Kubeadm as I alluded to in a previous post. The one tricky part is making sure that you have the pod-network-cidr explicitly specified when running kubeinit. In addition to turning off swap etc. I had no need to turn off/disable firewall, some people say they had to.

Installing ElasticSearch

So to test my new Kubernetes cluster, I wanted to play with elasticsearch. The instructions for that are relatively straightforward here https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-eck.html . Once the custom resource definition is installed, I started using the snippet here https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-elasticsearch.html to deploy a quick-start elasticsearch cluster, easy enough I thought. Keep in mind this isn't on a cloud based environment, this is going to be on dev kubernetes. 

ElasticSearch Didn't Find Storage -- Persistent Volumes

After I deployed my quickstart ES cluster, I saw the following error: "0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims". So essentially ES pods want to claim storage space (persistent volume) but don't know how. So I followed the following steps to resolve the issue:

  1. Created a storage class, I used a local storage class since I don't have NFS setup yet, see https://kubernetes.io/docs/concepts/storage/storage-classes/#local
  2. I created a persistent volume with the same storage class as the local one I just created
  3. I had to tweak the quickstart ES cluster template to:
    1. modify the volumeClaimTemplate to have it use the PersistentVolume I created in step 2
    2. modify the pod template to have the pod scheduled on a specific node that has persistent volume (remember this is a local storage)
    3. ES requires vm.max_map_count to be >= 262144
  4. I deployed the three objects and I finally had ES up and running

 Scripts

Local Storage

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

 

Persistent Volume

# see https://kubernetes.io/docs/concepts/storage/volumes/
kind: PersistentVolume
apiVersion: v1
metadata:
name: quickstart-elasticsearch-pv
labels:
type: local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
volumeMode: Filesystem
hostPath:
path: /your/path/here
type: Directory

 

ElasticSearch Modified QuickStart Operator Deployment:

#I retyped this for this post so I may have typos/bugs etc.
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 7.11.2
nodeSets:
- name: default
count: 1
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage # has to match what we used in the StorageClass object
podTemplate:
metadata:
labels:
app: elasticsearch-test
spec:
nodeSelector:
kubernetes.io/hostname: hostname-with-the-persistent-volume #if you only have a single node this won't be needed
initContainer:
- name: sysctl
securityContext:
privileged: true
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144'] #this is needed because by default Linux uses a lower limit than ES requires


When Installing Kubernetes Using Kubeadm ...

 If you're going to build your own Kubernetes cluster, then kubeadm is a really good tool for that.

One word of advice is that you should specify the --pod-network-cidr IP address range explicitly and don't rely on the defaults.

So, for instance, kubeadm init --pod-network-cidr=192.168.0.0/16 assuming that the 192.168 network address does not conflict or overlap with any other subnet address in your network.

Better yet, consider printing the default config options to a file first using kubeadm config print init-defaults > your-config-file.yaml then tweak these defaults to fit your need. Once you're happy with your tweaked config file, then run kubeadm init --config=your-config-file.yaml

 

Sunday, February 28, 2021

A Docker Image from Scratch

Initially, we need a minimal root filesystem.

    mkdir base-image
    cd base-image
    #assuming we're inside the base-image dir
    chr=$(pwd)
    
    mkdir -p dev/{pts,shm}
    touch dev/console
    mkdir etc
    touch etc/hostname  etc/hosts etc/resolv.conf
    ln -s /proc/mounts etc/mtab
    mkdir ./{proc, sys}
    
    #now we copy our application that is the target of containerization, in this case it's bash and a few other utils
    cp -v /bin/{bash,touch,ls,rm} $chr/bin
    #copy bash dependencies, ldd will tell us what bash requires at runtime to run
    list="$(ldd /bin/bash | egrep -o '/lib.*\.[0-9]')"
    echo $list
    for i in $list; do cp -v --parents "$i" "${chr}"; done
    
    list="$(ldd /bin/touch | egrep -o '/lib.*\.[0-9]')"
    echo $list
    for i in $list; do cp -v --parents "$i" "${chr}"; done
    
    list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"
    echo $list
    for i in $list; do cp -v --parents "$i" "${chr}"; done
    
    
    list="$(ldd /bin/rm | egrep -o '/lib.*\.[0-9]')"
    echo $list
    for i in $list; do cp -v --parents "$i" "${chr}"; done
    
    #run chroot to test
    sudo chroot . /bin/bash
    

Once chroot is working and we're able to jail the bash app, we proved that bash is able to run in isolation, it's got all it needs.
We now create the Dockerfile from scratch

        FROM scratch
        COPY bin/ /bin/
        COPY lib/ /lib
        COPY lib64/ /lib64
        COPY usr/ /usr/

        #RUN ["/bin/bash", "/bin/ls", "."]
        #ENTRYPOINT ["/bin/bash"]
        CMD ["/bin/bash"]
    

To build the image,
sudo docker build . -t bshell

To run the image
sudo docker run -it --rm bshell

[1] Using Chroot https://www.howtogeek.com/441534/how-to-use-the-chroot-command-on-linux/
[2] Docker: Up & Running 2nd Edition https://learning.oreilly.com/library/view/docker-up/9781492036722/ch04.html#docker_images

Sunday, June 14, 2020

Building Firefox on Windows 10

Building Firefox

The build tools linked here https://firefox-source-docs.mozilla.org/setup/windows_build.html do not like spaces in their paths.

For example, ./mach build step will fail with an error: "ERROR: GetShortPathName returned a long path name for C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\Hostx64\x64\cl.exe" or something like that. A number of solutions suggested here, https://bugzilla.mozilla.org/show_bug.cgi?id=1323381.

This is discussed here https://bugzilla.mozilla.org/show_bug.cgi?id=1323381 I personally do not like enable short names using fsutil because it will slow down directory enumeration. Here is what worked for me,
  • Create a link, a directory junction https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc753194(v=ws.11). The link will obviously have a shorter name with no spaces, for example Mklink /j C:\VS2019 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community The paths as shown in the example is what worked for me

  • Add a new environment path VC_PATH with value C:\VS2019\VC\Tools\MSVC\14.26.28801 make sure the value is actually a valid directory and update it to the latest if necessary.

  • Run (or rerun) ./mach configure. You may have to delete the config.cache file. (There is probably a command to clear a config)

  • Run ./mach build. My build was successful


Summary

  • Mklink /j C:\VS2019 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
  • set VC_PATH=C:\VS2019\VC\Tools\MSVC\14.26.28801 or add it throw the GUI to persist it
  • ./mach configure (you have to delete the existing config.cache
  • ./mach build

Links


Saturday, April 11, 2020

Configure NuGet Cache Directories

Powershell snippets to change where nuget caches packages. As they are, these lines will add a machine-wide environment variable.

[System.Environment]::SetEnvironmentVariable('NUGET_PACKAGES', 'D:\nuget\packages', [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable('NUGET_HTTP_CACHE_PATH', 'D:\nuget\v3-cache', [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable('NUGET_PLUGINS_CACHE_PATH', 'D:\nuget\plugins-cache', [System.EnvironmentVariableTarget]::Machine)
For more https://docs.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders

Monday, February 29, 2016

AngularJS: Change in Underlying Model Not Reflected in View


Struggling with an update to the view model that among other things affects the visibility of a DOM element. While the DOM element became visible, some of its properties where not updated. The DOM properties that were not updated include offset.top and offset.left. They were always zero even after the DOM element became visible.

This is perhaps because updating the DOM properties is not instantaneous but rather does take time. What comes to mind is the question of what if you force update to propagate?

So $scope.$apply will indirectly cause watchers of the model's properties to be notified of changes. $scope.$apply internally calls $digest and the documentation does not recommend calling $digest directly.

Therefore calling $scope.$apply seemingly fixes the issue. It, however, does not seem a recommended practice. See discussion here http://stackoverflow.com/questions/12729122/angularjs-prevent-error-digest-already-in-progress-when-calling-scope-apply

In my case what worked is waiting for the DOM to updated. The amount of time wait was chosen based on experimentation. The way to wait is using setTimeout or in the angular way $timeout.

Saturday, December 6, 2014

Is Perfect Square for BigInteger

For testing if an integer is a perfect square


   private bool IsPerfectSquare(BigInteger n)
   {
        
        var sqrt =  (BigInteger)Math.Round(Math.Exp(BigInteger.Log(n) / 2));
 return (sqrt * sqrt) == n;
    }
I took it from http://msdn.microsoft.com/en-us/library/dd268263(v=vs.110).aspx

Thursday, September 11, 2014

An Advantage of Using Current SynchronizationContext over Control.BeginInvoke

SynchronizationContext vs Control.BeginInvoke


Windows Forms and WPF framework do not allow modifications to UI elements and controls from a non-UI thread. So if a task thread wants to display a result on the UI or change a control to indicate state of some sort it has to somehow communicate with the UI thread and the UI thread should take care of displaying the UI updates, carry out the desired change to UI controls, etc.

There are two to accomplish this:

  • Capturing the SynchronizationContext as in the code snippet below which is assumed to part of a method in child class of the System.Windows.Form class:
      Task.Factory.StartNew(() =>
      {
        // update UI here
      }, this.cancelToken.Token
       , TaskCreationOptions.None
       , TaskScheduler.FromCurrentSynchronizationContext()
     );
    

  • Using Control.BeginInvok as in the code snippet below which also assumes to be with a child class of the the System.Windows.Form class:
    Task.Factory.StartNew(() =>
    {
        DoSomeWrok();
        Action updateUIDelegate = () =>{ UpdateUI();}; 
        /* ^^ a way of creating a delegate to be passed to BeginInvoke */
        this.BeginInvoke(updateUIDelegate); //will be execute on the UI thread.
        /* ^ this refers to the Form instance */
    }, this.cancelToken.Token
    );
    

    Notice in the above code we did not need to capture the current SynchronizationContext.

One Reason to Prefer Capturing Current SynchronizationContext:


Control.BeginInvok is not available in WPF. So if you are creating classes to be used in both Windows Forms and WPF then using SynchronizationContext is the portable way. Here is more from http://blogs.msdn.com/b/pfxteam/archive/2012/06/15/executioncontext-vs-synchronizationcontext.aspx:
We now have two different APIs for achieving the same basic operation, so how do I write my component to be agnostic of the UI framework?  By using SynchronizationContext.  SynchronizationContext provides a virtual Post method; this method simply takes a delegate and runs it wherever, whenever, and however the SynchronizationContext implementation deems fit.  Windows Forms provides the WindowsFormSynchronizationContext type which overrides Post to call Control.BeginInvoke.  WPF provides the DispatcherSynchronizationContext type which overrides Post to call Dispatcher.BeginInvoke.  And so on.  As such, I can now code my component to use SynchronizationContext instead of tying it to a specific framework.
I was curios how WindowsFormsSynchronizationContext mentioned in the article mentioned above implemented the Post method so I took a look at the code (reflected):


public override void Post(SendOrPostCallback d, object state)
{
 if (this.controlToSendTo != null)
 {
  this.controlToSendTo.BeginInvoke(d, new object[]
  {
   state
  });
 }
}

Tuesday, September 9, 2014

Rendering Partial View from C#

Rendering Partial View from Inside a Controller Action in C#:

Sometimes I find a need to a rendered HTML string from inside an action (a response to AJAX call for example).

The RenderPartialView function below assumes it's a member method of a class derived from the System.Web.Mvc.Controller class.

Function description: Renders the partial view and returns the generated Html. I think it's easier than returning the raw data and having jQuery generates the HTML. Params: partialViewFullPath - The path and extension to the partial view. for example, ~/Views/Controller/ViewName.cshtml    model - Almost always we expect a model Returns: HTML string generated by the the MVC framework itself.

   
public string RenderPartialView(string partialViewFullPath, object model){
    /* to avoid null ref exception when unit testing */
    if (HttpContext == null || HttpContext.Request == null)
    {
        return string.Empty;
    }
    if (string.IsNullOrEmpty(partialViewFullPath))
    {
        throw new ArgumentException("partialViewName");
    }
    ViewDataDictionary viewData = new ViewDataDictionary(model);
    var razorView = new RazorView(this.ControllerContext, partialViewFullPath
    , null, false, new string[] { "cshtml" });
    var sb = new StringBuilder();
    using (StringWriter sw = new StringWriter(sb))
    {
        using (HtmlTextWriter tw = new HtmlTextWriter(sw))
        {
            ViewContext viewContext = new ViewContext(this.ControllerContext
                            ,razorView,viewData, this.TempData, tw);
            razorView.Render(viewContext, tw);
        }
    }
    return sb.ToString();
}


The RenderPartialView function can be called as the following example code shows

        
[HttpPost]
public ActionResult SomeAction(int id)
{
    ///...
    var result = new AjaxReturnObjectModel();
    result.Success = true;
    result.Html = RenderPartialView("~/Views/Controller/PartialView.cshtml", model);
    return Json(result, JsonRequestBehavior.DenyGet);
}

Hope this helps.

Thursday, May 22, 2014

SQLite: How to Enforce Foreign Key Constraints

Enabling SQLite Foreign Keys:

SQLite lets create foreign keys but will not enforce them upon insertion or deletion. I spent sometime playing with this and it turns out that there are two ways to make SQLite enforce the foreign key constraint:

1) And the this is the easiest way. In the connection string you can specify that foreign keys should be enforce like so (tested using System.Data.SQLite ADO.NET driver):
<add name="ConnectionName" connectionString="Data Source=dbname.db;Version=3;New=True;Foreign Keys=True;" providerName="System.Data.SQLite"/>
2) For every connection you can turn on the foreign_keys pragama using the command
PRAGMA foreign_keys = ON; as documented here http://www.sqlite.org/foreignkeys.html#fk_enable

So with the second approach one can do something similar to the following pseudocode:

SQLiteConnection cn = new SQLiteConnection(...);
SQLiteCommend cmd = new SQLiteCommand(cn);
cn.Open();
cmd.CommandText = "PRAGMA foreign_keys = ON;"
cmd.ExecuteNonQuery(); /* so far we ensured that foreign keys constraints will be enforced */
cmd.CommandText = /* some SQL code here */
cmd.Execute ...

I prefer approach 1).



Friday, January 31, 2014

Passing Func When you Meant Expression

Queries are Very Slow

While working on a proof of concept project, I noticed my queries took longer than expected to run. The repository class uses an Entity Framework (Code First) DbContext. The function in the repository class in question had a signature that looked like:

public IEnumerable<entity> Find(Func<Entity, bool> whereExpression,int take,int skip){
return this.dbContext.Entities.Where(whereExpression).Skip(skip).Take(take);
}

The idea is I will let the client of the repository pass any expression that will return a boolean value to filter the entities collection.

I noticed the generated SQL was something like

select column1, .... columnn from dbo.table where <some_condition>
I did expect the output query to specify a limit to the query at the end (this was PostgreSQL). So I expected:
select column1, .... columnn from dbo.table where <some_condition> limit n;
I ran the same code against Microsoft SQL Server 2012 and the generated SQL had not top keyword to limit the number of returned rows.

What was Happening?

Basically the where operation and the take calls were not happening on the database server, they were being executed on the client-side, the C# console app in my case. The entire table (thousands of rows) of Entities was brought to the client and loaded in memory after the filtering and limiting took place. Very expensive and that explained why the query was much slower than I expected. 

Why was the Entire Table Loaded to Memory?

I just needed the top n rows so why the entire table loaded in memory? After browsing the documentation I came to the following understanding and conclusion. In LINQ if you enumerate a query it will cause the runtime to execute it to get the result. Enumerating a query is typically done via calls to function such as ToList(), or via a foreach expression. So which call in my two-line function was causing the Entities property to be executed and enumerated. Entities is of type DbSet which implements both IEnumerable and IQueryable and both interfaces have a Where method http://msdn.microsoft.com/en-us/library/gg696460(v=vs.113).aspx. Which implementation of where to call is determined by the type of the argument. Notice that IEnumerable's where looks like 
Whereas IQueryable's where looks like 

I noticed that when I called my Find function with Func<T,bool> as the type of the whereExpression variable, the Entities set was enumerated and loaded to memory as soon as the Where method is called. When I however pass an Expression (and not just a delegate) the following happened:
  • I got my limit statement (or top statement in T-SQL) in the generated SQL code
  • Therefore not all instances of Entity was loaded in memory
  • The query was faster as a result.
So the new signature of my Find function is 

public IEnumerable<entity> Find(Expression<func>Entity,bool>> whereExpression,int take,int skip)

Summary

There is a difference between passing a delegate Func or an Expression. Here is a good answer to the difference http://stackoverflow.com/a/3123181. Applying either a delegate or an expression has an effect on LINQ to Entities queries.


 

Thursday, October 3, 2013

Connect to Wireless Network from Command Prompt or Terminal

Why?

If you're Windows o Mac OS X is not configured to connect automatically to your wireless network, it can be a bit tedious to use the GUI in either OS to connect to your WiFi. Here are two commands to connect to a a wife:

Windows:

The netsh command and its subcommands is a powerful way to interact with windows networking subsystem. Follow this http://technet.microsoft.com/en-us/library/cc755301(v=ws.10).aspx for more on this command. Here is how to connect to a WiFi:

The command:

netsh wlan connect name=your_wireless_network_profile_name ssid=your_wireless_network_ssid

If you are not sure about the network profile (normally it's the same as the ssid) you can use netsh command to list all profile:

netsh wlan show profiles

If you want to see the available networks then use:

netsh wlan show networks

Netsh is a great command and can do a lot more.

Mac OS X:

The networksetup command is a powerful command in the Mac OS X environment to deal with network setup. 

To connect to a wireless network for example:

networksetup -setairportnetwork hardware_port your_wireless_network_ssid your_password

A typical value for hardware_port (wireless) is en1 (ethernet interface # 1).

There is more to this command for sure.

Tuesday, September 24, 2013

Array Traversal i++ vs i--

Array Bounds-Check Removal


One of the optimization done in .NET CLR is removing bounds-check when accessing arrays. It's done in certain cases and this excellent blog post discusses these cases (http://blogs.msdn.com/b/clrcodegeneration/archive/2009/08/13/array-bounds-check-elimination-in-the-clr.aspx)

Something that I found really interesting is that it matters as far as bounds-check elimination is concerned whether arrays traversed in an increasing or decreasing order.
for(var i=0;i<someArray.Length;i++){ //array access using i} vs. for(var i=someArray.Length-1;i>=0;i--) { //array access using i }

 So in accessing the array within with the first loop, the bound check is eliminated but in the in the second case (decreasing; i--). The mentioned posts recommend traversing the array in ascending order whenever possible.

Another useful advice from the post is that using the Length property in the condition statement of a for loop is better than using a local variable (unless the local variable is intended to access a subset of the array of course). Interesting stuff.



 
 
 
 

Tuesday, September 17, 2013

Generate SQL to Search All Columns in a Table

If you are searching for a given value in a table with numerous columns not knowing which column could match the value, you'll find it tedious to write as many OR clauses as columns in your table.

Here is a simple T-SQL script to generate SQL code with all the column names and the OR clauses.


 declare @sql nvarchar(max);
 select @sql = 'select * from MY_TABLE_NAME where ';
 select @sql = @sql + c.name + ' = ''value'' or '
 from sys.tables t 
  inner join sys.columns c on t.object_id = c.object_id 
  and c.system_type_id in(231,167) --this restricts target columns to just nvarchar,varchar types
  and t.name = 'MY_TABLE_NAME';
  
 select @sql = left(@sql,len(@sql)-3)+';'; -- remove the last or
 print @sql;

MY_TABLE_NAME has to be changed to your specific table of course. This script can be improved to add conditional casting. When the column type (system_type_id) is string then no casting is needed but when integer then convert to varchar and when the type is datetime for example then use convert(varhcar(10),101) for example.

Sunday, July 21, 2013

C#/VB.NET Optional Parameters and the MissingMethodException Exception

Optional Parameters 

Optional parameters is a useful feature in C# and VB.NET languages. Adding an optional parameter to a method can sometimes make re-factoring a bit easier and less invasive. There is however a catch one should know. I ran into this situation a few days ago and here is my attempt to describe it:

Initially

Suppose you have a library, let's call it OptionsLib. In this class library lets say we have class called Common. In this Common class there is a method call DoSomeWork whose signature looks initially like

public void DoSomeWork(){
   DoStepOne();
   DoStepTwo();
   DoSomeOtherStep();

}

Now we have a consumer of this OptionsLib library and let's call it OptionsClient and it exists in its own assembly. So we have two assemblies: OptionsLib v1.0.0.0 and OptionsClient v1.0.0.0.

New Version: Minor Change

You've decided to make a minor change to your OptionsLib.Common class. Namely you wanted to add some conditional logic to the DoSomeWork method. So the new method would look something like:

public void DoSomeWork(bool someCondition = true){
   DoStepOne();
   DoStepTwo();
   if(someCondition){
       DoSomeOtherStep();
   }
}

There are probably other libraries that depend on the OptionsLib library so making the new parameter optional alleviates you from having to change the way the method called everywhere. The existing behavior is retained by making the new parameter optional and giving it a default value of true. So now re-compiling the whole solution will yield no errors as a result of the new optional parameter. The compiler will realize the new parameter is optional and will take care of passing the default value for you everywhere the method DoSomeWork is called.

The Issue: System.MissingMethodException

Let's say you found a bug in some of the libraries that use OptionsLib library or a change is made to one of its clients and you wanted to push that change to existing installations. In our example, suppose we may have fixed some bug or added a feature to the OptionsClient.dll assembly. So now OptionsClient.dll is compiled against the new version of OptionsLib, the version with the optional parameter change. In the existing installations however, the OptionsLib does not have the optional parameter we added.

For the most part placing the new OptionsClient.dll assembly in existing installations will be OK. It will find its referenced assemblies in the existing installations and everything seems to work fine. Until it starts calling the method DoSomeWork which in the new version has an optional parameter but not in the existing version. So in reality the new OptionsClient call of DoSomeWork looks like:
...DoSomeWork(true); // my understanding is that the compiler passes true for you                                               // because it's optional and the default is true
When the above call is made the runtime will complain because there is no method named DoSomeWork in v1.0.0.0 of OptionsLib that takes a boolean; there is one with no parameters at all but it's not what was called. The runtime then throws the System.MissingMethodException exception. So you'll realize that you may need to also recompile and ship the OptionsLib v1.0.0.1 the one with optional parameter

I Learned

Optional parameters are useful but sometimes adding them to a library can break dependents assemblies on this the changed library when the dependent assemblies are deployed alone without the changed library. I think I'd prefer method overloading when re-factoring.

http://msdn.microsoft.com/en-us/library/dd264739.aspx optional parameters
http://msdn.microsoft.com/en-us/library/zk1a255s(v=vs.80).aspx MissingMethodException

 

Sunday, June 2, 2013

Entity Framework Code First Does Not Create Database

Where is the Database?

I spent more time than I should have trying to troubleshoot why my database not being created. My DbContext-based class looked like:

    public class TakeNoteContext : DbContext
    {
        public TakeNoteContext()
            : base("name=TakeNote")
        {
            
        }
        public DbSet Posts ;
        public DbSet Users;
        public DbSet PostTypes;
        public DbSet SourceTypes;

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);
            //an alternative to using attributes
            modelBuilder.Configurations.Add(new PostConfiguration());
        }
    }

Everything looked right to me, initially. And later I noticed that I was using fields and properties for my DbSet data members.

The correct way:

    public class TakeNoteContext : DbContext
    {
        public TakeNoteContext()
            : base("name=TakeNote")
        {
            
        }
        public DbSet Posts { get; set; }
        public DbSet Users { get; set; }
        public DbSet PostTypes { get; set; }
        public DbSet SourceTypes { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);
            //an alternative to using attributes
            modelBuilder.Configurations.Add(new PostConfiguration());
        }
    }

The interesting thing is that the database can be created if I call ctx.Database.CreateIfNotExists(); directly even if I used fields. There might other reasons why your database is not created. My sure your connection is correct, for example.

Monday, May 27, 2013

WordPress Links not Working after Site Move

Reset Permlinks

I helped moving a wordpress blog from one directory to another (from a directory to its parent) and after the move, all links stopped working and returned a 500 Internal Server Error. Notice it was not a 404 file not found error.

After some search, it was suggested on a forum (sorry I don't have the link) that reset permlinks fixes the issue. This is important if the site url and home changes. Basically from Settings -> Permlinks , hit Save. This will cause all permlinks to reflect the new url.

Having all links broken was scary. I hope this tip helps someone.


Thursday, May 2, 2013

Architecting .NET Applications for the Enterprise

Microsoft® .NET: Architecting Applications for the Enterprise (amazon)


A great book, I think, on software architecture using the .NET framework


The first part of the book is on Principles of software architecture. The seconds part is on the "Design of the System". This second part is then divided into a number of chapter. Each chapter is dedicated to one layer of the system. Business layer, Service layer, Data Access Layer etc.

My notes here are on the design of the business layer. The authors presented a number of patterns starting with the simplest and progressing to the most complex one that's suited to applications where the business logic involves much more that data insertion and retrieval.

BLL Patterns

Transaction Script Pattern

Think of an ASP.NET page with controls whose events are handled by code-behind (or MVC actions) code. The code then interacts with data store according following a script of known steps. This is a very simple pattern with no object-oriented design.

Command Pattern

The authors then talk about the command pattern as one step above the TS pattern. Each action that the system does is incapsulated in a class with a common interface. What's interesting here is that since actions are represented as classes, actions or a series of them that participating in a transaction, can be serialized.

Table Module Pattern

What's interesting about this pattern is that the BLL logic is grouped into components each of which deal with one entity. The component or class does not represent the entity but rather serves as a gateway to the table holding the instances of that entity in the database. Code following this pattern tends to be heavy on DataSet or similar data container but not a generic .NET container. DataSets are awful. 

Table Data Gateway Pattern

In this pattern, another layer is added between the BLL logic and the code directly talks to the database, hence Gateway.

Active Record Pattern

Each data entity is represented by class. Unlike the TM pattern, what is represented here is the individual rows and not the entire table. This allows for use of .NET generic containers. 

A class represents a row and all the logic that can be done on that data. The data handling (read,write, update and deleted) can be done either with this class or in separate DAL specific class.

The simplicity of this pattern, its cleanliness and its strongly-typed nature of representing entities make it a good choice for applications that are not very complex. Have said that however, I recommend taking a look at http://misko.hevery.com/2009/06/29/active-record-hard-to-test/.

Interestingly, the authors talk about LINQ-to-SQL and how it can be considered an Active Record pattern implementation.

Domain Model Pattern

When the complexity of a system grows and business logic involves operations that far exceed interactions with the database, the DM pattern is ideal. The focus here is on modeling the domain problem into a set of interconnected objects. The focus is also on the logic and interactions between these objects with no regard (at least at the BLL) to how data is persisted. 

Summary

A few patterns caught my interest while reading the Microsoft® .NET: Architecting Applications for the Enterprise. These patterns are primarily used when designing the business logic layer. Patterns discuss include, Transaction Script, Table Module, Active Record and Domain Model.