28 Oct

Sharing Code with Dependency Injection

This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.

  1. Linked Files
  2. Conditional Compilation
  3. Partial Classes
  4. Inheritance
  5. Dependency Injection

What is Dependency Injection?

Dependency Injection is a form of inversion of control where the consumer of a service passes some of the objects on which that service is dependent to the service, rather than having the service create them.

How do I do it?

In this case we’re not going to use a Dependency Injection framework, we’re going to use what I call “the poor mans dependency injection”.  I’m doing it this way to keep it simple and this could still work well with a framework.

First we’re going to create a Portable Class Library and in that library we’re going to define an interface for our data storage methods

public interface IMyStorage
{
    void Save(string key, object value);
    object Get(string key);
}

The we’re going to move our MainePageViewModel class to that library.  We need to modify that class to accept an IMyStorage in it’s constructor, then use that object to get and save it’s data.

public class MainPageViewModel : INotifyPropertyChanged
{
    private IMyStorage _myStorage;
    public MainPageViewModel(IMyStorage myStorage)
    {
        _myStorage = myStorage;
    }

    private string _helloMessage = "Hello World";
    public string HelloMessage
    {
        get { return _helloMessage; }
        set
        {
                
            if (_helloMessage != value)
            {
                _helloMessage = value;
                RaisePropertyChanged("HelloMessage");
            }
        }
    }

    private string _name = "";
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                _name = value;
                RaisePropertyChanged("Name");
            }
        }
    }

    public ICommand SaveAction { get { return new RelayCommand(() => Save()); } }

    public ICommand LoadAction { get { return new RelayCommand(() => Load()); } }

    private void Load()
    {
        object name = null;

        name = _myStorage.Get("Name");

        if (name != null)
        {
            HelloMessage = "Load " + name.ToString();
        }
    }

    private void Save()
    {
        _myStorage.Save("Name", Name);

        HelloMessage = "Save " + Name;
    }

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

In the platform specific projects we need to add a reference to the PCL and create a class that implements IMyStorage. Windows Phone specific code below

class MyStorage : IMyStorage
{
    public void Save(string key, object value)
    {
        if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
        {
            IsolatedStorageSettings.ApplicationSettings[key] = value;
        }
        else
        {
            IsolatedStorageSettings.ApplicationSettings.Add(key, value);
        }
    }

    public object Get(string key)
    {
        if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
        {
            return IsolatedStorageSettings.ApplicationSettings[key];
        }
        return null;
    }
}

Then in the MainPage.xaml.cs where we are setting the page’s datacontext to the MainPageViewModel, we need to make sure we’re passing a new instance of the MyStorage class (this is the actual Dependency Injection, poor man’s style)

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    this.DataContext = new MainPageViewModel(new MyStorage());
}
14 Oct

Sharing Code with Inheritance

This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.

  1. Linked Files
  2. Conditional Compilation
  3. Partial Classes
  4. Inheritance
  5. Dependency Injection

What is Inheritance?

I’m just going to go ahead and assume you understand inheritance, but I’m keeping this section to stay with the theme from the other posts in this series.

How do I do it?

To share code in this way we’re going to create an abstract class MainViewModelBase with an abstract method defined for the place where we’re going to do our platform specific coding.  We can share that class between projects either through file linking or creating a Portable Class Library

abstract class MainPageViewModelBase : INotifyPropertyChanged
{
    protected abstract void Load();
    protected abstract void Save();

    //The rest of the common code would go here
    private string _helloMessage = "Hello World";
    public string HelloMessage
    {
        get { return _helloMessage; }
        set
        {
            if (_helloMessage != value)
            {
                _helloMessage = value;
                RaisePropertyChanged("HelloMessage");
            }
        }
    }

    private string _name = "";
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                _name = value;
                RaisePropertyChanged("Name");
            }
        }
    }

    public ICommand SaveAction { get { return new RelayCommand(() => Save()); } }

    public ICommand LoadAction { get { return new RelayCommand(() => Load()); } }

    

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;        
}

Then we’re going to inherit from that class in each of our projects.  Here’s what the code for the Windows Phone project looks like

class MainPageViewModel : MainPageViewModelBase
{
    protected override void Load()
    {
        object name = null;
        if (IsolatedStorageSettings.ApplicationSettings.Contains("Name"))
        {
            name = IsolatedStorageSettings.ApplicationSettings["Name"];
        }
        if (name != null)
        {
            HelloMessage = "Hello " + name.ToString();
        }
    }

    protected override void Save()
    {
        if (IsolatedStorageSettings.ApplicationSettings.Contains("Name"))
        {
            IsolatedStorageSettings.ApplicationSettings["Name"] = Name;
        }
        else
        {
            IsolatedStorageSettings.ApplicationSettings.Add("Name", Name);
        }
        HelloMessage = "Hello " + Name;
    }
}
01 Oct

Sharing Code with Partial Classes

This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.

  1. Linked Files
  2. Conditional Compilation
  3. Partial Classes
  4. Inheritance
  5. Dependency Injection

What are Partial Classes?

Partial Classes are a way to split a class up into multiple files. It is frequently used when one part of your class is generated code and another part is written by hand.  In this case we’ll use partial classes to separate code that is shared between platforms and code that is platform specific.

How do I do it?

First you would need to use linked files to share the code between your projects. Then you need to change the class declaration to include the keyword partial.

partial class MainPageViewModel

Then you create a new files in each of your projects.  In this example we’ll create MainPageViewModel.WP8.cs and MainPageViewModel.W8.cs.  The WP8 file would be created in the Windows Phone project and the W8 file would be created in the Window 8 project.  We then need to include that same class declaration in those files.

Then we just move the methods with platform specific code into those platform specific partial classes.

The WP8 file would look like this:

partial class MainPageViewModel
{
    private void Load()
    {
        object name = null;
        if (IsolatedStorageSettings.ApplicationSettings.Contains("Name"))
        {
            name = IsolatedStorageSettings.ApplicationSettings["Name"];
        }
        if (name != null)
        {
            HelloMessage = "Load " + name.ToString();
        }
    }
}

The W8 file would look like this:

partial class MainPageViewModel
{
    private void Load()
    {
        object name = null;
        if (ApplicationData.Current.LocalSettings.Values.ContainsKey("Name"))
        {
            name = ApplicationData.Current.LocalSettings.Values["Name"];
        }

        if (name != null)
        {
            HelloMessage = "Hello " + name.ToString();
        }
    }
}
27 Aug

Sharing Code with Conditional Compilation

This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.

  1. Linked Files
  2. Conditional Compilation
  3. Partial Classes
  4. Inheritance
  5. Dependency Injection

What is Conditional Compilation?

Conditional Compilation tells the compiler to selectively compile code.  Many developers use these to run certain code only while in debug that they don’t want to run in production.

#if DEBUG
    //do some stuff
#endif

How do I do it?

The first step would be to link a file between two projects.  Then you can either use an existing Conditional Compilation Symbol or create your own.  For example Windows Phone 8 defines SILVERLIGHT and WINDOWS_PHONE as Conditional Compilation Symbols.  You see see what symbols have been defined by your project and even add your own by going to the Build tab in Project Properties.
CompilerDirective

To use the Conditional Compilation Symbols you just use the #if statement.  For example if you are using a namespace exists in Windows Phone, but doesn’t exist in Windows 8 you could do this:

#if WINDOWS_PHONE
using System.IO.IsolatedStorage;
#else
using Windows.Storage;
#endif

The System.IO.IsolatedStorage using statement will only be compiled in the Windows Phone projects.  The Windows.Storage using statement will be compiled in all other projects.

15 Aug

Sharing Code with Linked Files

This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.

  1. Linked Files
  2. Conditional Compilation
  3. Partial Classes
  4. Inheritance
  5. Dependency Injection

 What are Linked Files?

Linked files are a way for two or more projects to both reference the same file.  One project generally keeps that file under it’s file structure, other projects reference the file there.  You can open the file from any of the projects as you normally would and edit it.  All changes are saved to the one file.

Be Aware

  • You need to manually link the files.  If you have 50 code files you want to share between project, you need to add those 50 files as links individually.
  • If you rename a file that has been shared, you need to delete the old link and add the new link.

How do I do it?

Go through the regular process for adding an existing file, but after you’ve selected the file you need to select “Add as Link” from the dropdown at the bottom.

Link Files Dialog

06 May

Automating the compare of 2 rows in a trigger

I just answered this question on StackOverflow about how to generically compare an inserted row to a deleted row within a trigger. I started by just commenting that it would be a good place to do a little code generation, but something about the problem wouldn’t let me put it down. Here’s what I came up with.

First I created a function that would return the query that would actually do the comparison. Notice that I’m comparing #inserted and #deleted rather than inserted and deleted.  This is because we don’t have access to the inserted and deleted tables when we’re running the comparison query in an exec()

create function GetChangedRowsQuery(
	@TableName				varchar(50), 
	@PrimaryKeyColumnName	varchar(50),
	@RowVersionColumnName	varchar(50) = ''
)
returns varchar(max)
as
begin
	
    declare 
	@ColumnName varchar(50),
	@GetChangedRowsQuery varchar(max)

    select @GetChangedRowsQuery = 
           'select isnull(a.' + @PrimaryKeyColumnName + ', b.' 
           + @PrimaryKeyColumnName + ') 
      from #inserted a
      full join #deleted b 
        on a.' + @PrimaryKeyColumnName + ' 
           = b.' + @PrimaryKeyColumnName + '
     where '

    declare ColumnCursor cursor Read_Only
    for select Name
          from Sys.columns
         where object_id = Object_Id('Member')

    open ColumnCursor
    fetch next from ColumnCursor into @ColumnName
    while @@FETCH_STATUS = 0
      begin
	if (@ColumnName != @PrimaryKeyColumnName 
            and @ColumnName != @RowVersionColumnName)
	  begin
            select @GetChangedRowsQuery = @GetChangedRowsQuery 
                + '((a.' + @ColumnName + ' != b.' + @ColumnName 
                + ' or a.' + @ColumnName + ' is null 
                    or b.' + @ColumnName + ' is null) 
                and (a.' + @ColumnName + ' is not null 
                     or b.' + @ColumnName + ' is not null))' 
                + char(13) + '      or ' 
          end
        fetch next from ColumnCursor into @ColumnName
      end
    close ColumnCursor
    deallocate ColumnCursor

    select @GetChangedRowsQuery 
           = substring(@GetChangedRowsQuery, 0, len(@GetChangedRowsQuery) -7)

    return @GetChangedRowsQuery
end

Next, I created a trigger.  It creates the #inserted and #deleted temp tables, get’s the query from the function, creates a temp table to hold the results.  Then it inserts the result into the temp table.  I’m just selecting the top 10 changed rows, but you could do whatever you needed to do with the changed rows at this point.

create trigger TestTrigger on Member for Insert, Update, Delete
as
begin
	
    select *
      into #Inserted
      from Inserted

    select *
      into #Deleted
      from Deleted

    declare @GetChangedRowsQuery varchar(max)

    select @GetChangedRowsQuery 
            = dbo.GetChangedRowsQuery('MemberTrash', 'MemberId', '')

    create table #Temp (PrimaryKey int)

    insert into #Temp (PrimaryKey)
    exec (@GetChangedRowsQuery) 

    select top 10 *
      from #Temp

    drop table #Temp
    drop table #Inserted
    drop table #Deleted
end
02 May

Unsubscribe from everything

I recently moved my email from Gmail to Outlook.com. It’s not a small deal. I needed to get all my friends and family to update their contact info for me, and I’ve had to update my contact info on countless sites. As part this move I also started unsubscribing to pretty much anything that came into my Gmail account, but not signing up to receive those emails in my Outlook.com account.

Unsubscribe All the Things

The results have been wonderful. After about 2 weeks, I now only receive 1-2 emails a day, mostly from people I want to get emails from. I don’t really know how many emails I was receiving before, but I can tell you it’s really refreshing to be receiving so few.

I’ve added a reminder to my calendar for next year to spend a week or two unsubscribing from all the junk that builds up as I try out various new services. You should do the same.

14 Mar

AngularJS URLs missing trailing slash

I ran across this problem trying to deploy an Asp.Net MVC website with an AngularJS front end.  Everything worked fine as long as the site was deployed as it’s own website within IIS, but when we deployed to an Application folder within an existing site things started going wrong.

The problem was that the URLs were not getting their trailing slashes properly.  IIS adds a trailing slash to URLs when the last segment of the address refers to a folder rather than a file.

http://somesite.com/AngularApp should have been converted to http://somesite.com/AngularApp/

Since it wasn’t getting converted I was getting http://somesite.com/AngularApp#/ rather than http://somesite.com/AngularApp/#/

The fix I settled on was to check the URL of the request when it came in and if it matched the root url, but didn’t have the trailing slash, add the trailing slash.  I just added the following code to the Global.asax

protected void Application_BeginRequest()
{
    if (Request.ApplicationPath != "/" 
            && Request.ApplicationPath.Equals(Request.Path, StringComparison.CurrentCultureIgnoreCase))
    {
        var redirectUrl = VirtualPathUtility.AppendTrailingSlash(Request.ApplicationPath);
        Response.RedirectPermanent(redirectUrl);
    }
}
21 Jan

Show File Extension in Sharepoint Document Library

I was recently tasked with changing the view in our TFS Project Portal’s document library to show the file extension so you knew whether you were opening a PDF, Word Document, PowerPoint or something else for which you might not have the software installed.  There is an easy way and a hard way, and the guidance I received from a few Google searches skipped a few steps on the hard way.

Easy Way

  1. Open the Document Library
  2. Click on the Library Tools -> Library tab at the top
  3. Scroll to the bottom and click the view you wish to change
  4. Check “Name used in forms” column

This adds a new column with the full file name and extension, but it’s not clickable to view the document, so you end up with two columns for document name, the name and the name with extension.  This is why I ended up going down the hard way.

Hard Way

  1. Open the site in SharePoint Designer
  2. Click Lists and Libraries and open the Document Library you want to modify
  3. Open the View you want to modify
  4. Right click on the first row in the Name column and select Insert Formula
  5. In the Edit XPath expression box enter something that is easily searchable ie. xxxxxxxx
  6. Click OK
  7. Switch to the Code View
  8. Search for your xxxxxxx and delete the element it created
  9. Right above or below that should be an element like so <xsl:value-of select=”$thisNode/@FileLeafRef.Name” />
  10. Replace that with <xsl:value-of select=”$thisNode/@FileLeafRef.Name” /><xsl:if test=”$thisNode/@FileLeafRef.Suffix!=””>.<xsl:value-of select=”$thisNode/@FileLeafRef.Suffix” /></xsl:if>
  11. Save, exit and you’re done

The examples I found online left out steps 4-8, and until I did those the <xsl:value-of select=”$thisNode/@FileLeafRef.Name” /> element didn’t exist.

06 Jan

New Year’s Resolutions 2014

Here’s my list of New Year’s Resolutions for 2014:

Blog More

Historically, I only wrote technical posts whenever I came across something really novel and wasn’t so specific that I didn’t think anyone else can use it.  This year I’m going to loosen my standards for a technical blog posts.  That means there should be more posts, but some of them might just be a different spin on things that others have covered, or things that are really specific and may not be as useful to a broad audience.

Find more ways to share knowledge

For most of last year I shared an office with a very green developer.  Helping him learn the ropes has also been a great learning experience for myself.  Having to explain some concepts I take for granted to a beginner stretched me in ways I didn’t know I needed to be stretched.  I’d like to explore other ways to share what I have learned.  I have already volunteered to do a short talk on T4 at my local users group (after the main talk), hopefully I’ll be invited back after that.  I’m also going to keep a lookout local volunteer opportunities for things like Hour of Code

Networking

I’ve worked with and met a lot of great people, but many of them I haven’t spoken with in years.  My goal is to reach out to someone twice  a week either through email or phone.

Personal Stuff

I also have a few resolutions on a more personal level:

Go to bed earlier – I’m an early riser by nature, and every thing in life is easier when I’m well rested

Lose weight – It’s the cliche New Year’s resolution I know, but I lost a bunch of weight before my youngest son was born last April and have packed on the pounds since then.  I make bad food related decision when I’m tired and a new baby isn’t anything if it isn’t tiring.  I’d like to lose 40 pounds and keep it off for good.  No crazy diet here, more of a lifestyle change.  Just eating a little less and working out a little more.  I should be able to lose all of that weight by the end of 2014.