Archive for General

Local Build Using/Incrementing Team City Version Number

Jun 18

On my current project we have a problem in that one of the assemblies we use requires an expensive license that is per computer so our build server would need it’s own license which we are not doing at this point. Now I need to run our publish deploy script locally which means manually increasing the version number on each build. Something that has been missed before causing a new version to overwrite an old version… which is bad… very bad.

To combat this I started digging and found a way to have my build script use and change the TeamCity build counter remotely using their REST API.

First open up http://[Server]/httpAuth/app/rest/projects/ and find your project you want to work with.

Then open up http://[Server]/httpAuth/app/rest/projects/id:project2 and find the configuration you want to work with.

Then open up http://[Server]/httpAuth/app/rest/buildTypes/bt5/settings/buildNumberCounter to get the current build counter

Here is the C# code I use

    public class TeamCityVersionIncrementer
    {
        private readonly string _buildCounterUri;
        private readonly NetworkCredential _credentials;
        public TeamCityVersionIncrementer()
        {
            _buildCounterUri = “http://[server]/httpAuth/app/rest/buildTypes/bt5/settings/buildNumberCounter”;
            _credentials = new NetworkCredential(“[user]“, “[pass]“);
        }
        public int Increment()
        {
            int originalCounter = GetBuildCounterFromTeamCity();
            UpdateCounter(originalCounter + 1);
            int counterAfterIncrement = GetBuildCounterFromTeamCity();
            if (counterAfterIncrement != originalCounter + 1)
            {
                throw new ApplicationException(“Expected build to be incremented to ” + (originalCounter + 1) + “but was ” + counterAfterIncrement);
            }
            return counterAfterIncrement;
        }
        private int GetBuildCounterFromTeamCity()
        {
            WebRequest webrequest = WebRequest.Create(_buildCounterUri);
            webrequest.Credentials = _credentials;
            webrequest.Method = “GET”;
            WebResponse webResponse = webrequest.GetResponse();
            using (var reader = new StreamReader(webResponse.GetResponseStream()))
            {
                string readToEnd = reader.ReadToEnd();
                return int.Parse(readToEnd);
            }
        }
        private void UpdateCounter(int number)
        {
            byte[] arr = Encoding.UTF8.GetBytes(number.ToString());
            var request = (HttpWebRequest)WebRequest.Create(_buildCounterUri);
            request.Method = “PUT”;
            request.ContentType = “text/xml”;
            request.ContentLength = arr.Length;
            request.Credentials = _credentials;
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(arr, 0, arr.Length);
            dataStream.Close();
            var response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode != HttpStatusCode.NoContent)
                throw new ApplicationException(“Unexepected status code: ” + response.StatusCode);
        }
    }

Hope that helps someone in this rare situation!

Filed Under: General

Syncing Facebook/Meetup/Google Calendar On My phone

Jun 5

One issue I have been running into is not adding my facebook/meetup events onto my phone. I then miss these events or forget until the last minute. I thought there must be a way to automate this and after a bit of tinkering I got it to work.

I am on an iPhone that uses Google Calendar as it’s calendar provider. I assume that the steps will be the same for any device that supports Google Calendar:

Facebook

  1. Click events on the left
  2. click export events
  3. copy the url
  4. login to google calendar
  5. under other calendars click “add by url”
  6. paste in the url for your fb calendar

Meetup

  1. On the main page click the “add to” right above the calendar
  2. Click the Google Calendar icon
  3. It will open up the google calendar website and prompt you to add it

Once this is done the calendars did not appear on my phone. Some people posted to add them by visiting: https://www.google.com/calendar/iphoneselect which did nothing for me.

After a bit more reading I found that if I opened http://m.google.com/sync on my phone I could check off the calendars I wanted to snyc and viola there they were.

 

Filed Under: General

The Update

Apr 9

Well my life has been busy with lots of personal drama. Hopefully that is all behind me now. I have really lost the urge and drive to blog (plus being crazy busy does not help). For the future I am going to be focusing posts on some of my open source work. Namely FluentBuild and FluentFilesystem.

FluentBuild, is my open source fluent interface around doing builds. It has been coming along as I get time and it is almost to a place that I like it. I found the filesystem interface really became its own beast so I am spinning that off into its own library (https://github.com/GotWoods/FluentFs). I have a few remaining beefs with FluentBuild:

1) Having to append .Execute() to the end of a lot of the tasks. I always forget and I wrote the damn thing. I will be changing the interface around to more of a Task.Build(details go in here); I am thinking. This should make things simpler to me.

2) The calling out to external executables (which happens a lot) is not where I want it to be at. I am trying to find some time to revise this. My goal is to have a set of injectable processors that can analyze the output from the executable and determine what to do. This will allow for more fine grained control over how output is dealt with. Most of this should be transparent to the user but it will of course be extendable and simple to use.

 

So the roadmap to me is this:

  1. Now that FluentBuild and FluentFS is split I need a way to merge it all back simply so that users are not dependent on two projects. It also guarantees compatibility.
  2. Possibly migrating to github (I enjoyed the experience with FluentFS so FluentBuild may get migrated as well)
  3. Removing the need for .Execute() on methods
  4. Reworking the executable callouts.

So lots of work ahead of me on this but getting closer to what I want it to do. I have been using it on several projects and I feel that it is getting closer to a release.

I would like to thank all the people who have given feedback, patches, and bug reports for the project!

Filed Under: General

Dropping my MVP

Feb 2

I have decided to drop out of Microsoft’s Most Valuable Professional Program. I have decided this for many reasons. Mainly I feel the program has no value to me and that MVPs are of no value to MS.

Experts

MS states how they have these “experts” in the community and that are involved in the products. While I have met some really smart MVPs I have also met some that are so out to lunch on things yet MS still considers them experts. To me this completely devalues the MVP program. I am definitely no exception to this. I am a MVP in developer security yet I don’t consider myself to be an expert. Interested yes. Expert no.

The way you get in is by contributing to the community. I had done lots of this and it was really nice to get recognized for it. Once you are in you are supposed to be this expert that provides feedback to the products that MS is building. Now this is where the program breaks down.

Products

Firstly most products you never hear about until it is too late. I hear about more MS technology from the mainstream media than I do from the MVP program. As a MVP who is supposed to be like an insider I thought that they would be looking to us for feedback on these technologies. But they don’t. They will take it after the product is released though but by then there are usually too many issues with the technology to be overcome.

While some products are great there are a big few that still irritate me:

 TFS is garbage if you have used anything else. I should never have to struggle to get things under source control as much as I have with this product. I should never have to struggle for days/weeks to install it. I should never have so much trouble configuring it or applying checkin policies. If any MVP worth their salt was asked about this then MS should know this.

MSBuild is another failed technology to me. It does not come close to the power of Nant so if I am going to pay the XML tax I will pay it with Nant. I will say that it is nice that proj files are msbuild files yet whenever I have had to customize my builds with MSBuild I want to hurt myself. At first I thought it was the learning curve but to me the product just does not meet my needs. Again if an MVP that uses a build technology was asked then MS would have known about this.

MSTest also missed the mark to me when they said it was not geared towards people who do TDD. Really? No one else does TDD? I am the only MVP that does? I think not.

The big one that continues to bug me is Entity Framework. At the ‘08 MVP summit a lot of the MVPs that saw it before it was announced pointed out the serious issues it has. At the ‘09 summit we were excited to see the improvements they had made but instead we were shown the same crap that was the ‘08 entity framework. This spawned off the Entity Framework Vote Of Non Confidence and finally in ’11 we have some of the changes that we said were so needed in ’08. Good job valuing the input of the people that actually have to use the crap you put out.

MS “Listens”/”Cares”

To me it seems that MS having MVPs is a way for MS to feel that they are in touch with the community at large. This is great for a company to do but it seems like the feedback that is given falls on deaf ears for many products. I am not saying that this is for all products though as some do really care about feedback. For the most part though it feels like any feedback given just falls into a void. When I asked for some contacts for TFS/MSBuild/MSTest I was told to send my feedback to my MVP lead and they would forward it on…. Because that is open. You want MVPs to be involved yet filtered (I felt anyways). I have had more interaction with MS staff by tweeting things that I have through the MVP program.

The other big issue I have with MS in general is being treated like we will jump through hoops to help them succeed. There have been a number of “tech x is launching in a few weeks so build something” so we can showcase it emails I have received. Well that is great but how am I going to build a good app on a new technology with little documentation and no access to anyone at MS who can give me some accurate answers to issues? I understand that MS staff are not there to troubleshoot my application but on new/unreleased technology it would be good to have some sort of access if only an internal message board.

There are some internal lists at MS for MVPs as well. I found out about the security one after being a security MVP  for OVER A YEAR. Now that I am on it…. Not much happens. There is little in the way of solicitation for feedback and there is little feedback provided. I assume this is because the security space is pretty quiet but then I am surprised to see things at the summit that I had no idea were being developed.

The most surprising thing to me was when I told my MVP lead that I was not interested in participating in the program. The response was: “No problem.  Thanks for letting me know Dave.  Good luck in the future”. I expected maybe a bit more of a “Why?” response but I am not surprised that MS does not care about what other people think. Maybe, because I have become harder on MS that they are happy to be rid of me. Who knows.

Maybe I am being hard on the program. Our MVP lead is great and tells us that whatever we need he will make happen. Great but how about you let us know some of the things that you can do for us? If you want something like WP7 to succeed get more than 5 dev phones and let us know you have them if we want to build applications. If MS is thinking of a new technology solicit the MVPs for people that use or have an interest in the new tech and get their feedback at the START of development instead of at the end.

Rewards

The MVP award is given to those that contribute to the community. I enjoy doing this and I will continue to do this whenever I can. Unfortunately it costs a lot of time and money to contribute to the community. If I give a talk I have spent 40 to 200 hours preparing (yes 200 hours on a 1 hour talk) plus the costs to travel to another city, food, and accommodation.  MS’s reward is a MSDN subscription and half of a hotel room if I attend the summit (there used to be more benefits but they have been rolled back to save costs). It would probably be more affordable for me to purchase an MSDN subscription on my own and stop speaking entirely. I have gained no additional work from the MVP program, no additional speaking gigs, and have not made relatively few connections to others because of the MVP program.

Fin

The program has become a black mark to me. It does not contain just experts (heck, they let me in). It does not certify that anyone has a clue about anything (and some of the MVP only lists prove this). It has not opened any doors for me. It does not help me stop MS from releasing crap that I have to work with. All it does for me is give me an MSDN subscription and another line on my resume.

Filed Under: General, Rants

Security Trends

Dec 29

I have been around computers for most of my life and for the past ten years I have been involved in corporate IT on both the network side and the programming side. I was reflecting on some of the changes and trends over the past decade and thought I would share them.

  1. We have realized that network security is important. Every organization I visit seems to have a firewall, antivirus, and windows updates turned on. Ten years ago it was every computer was connected straight to the internet with an exposed c$ share it seems like. Finally most corporate (and many home users) seem to have taken some basic security measures.
  2. Users still click on anything that pops up on the screen until they get the application/website to work. I have tried to educate people on this but it has become apparent to many of us in the industry that users just want things to work and it only when they go wrong that they care. For instance, my parents install every plugin they are prompted to as they feel that if it was bad their antivirus would catch it. I don’t fault them for it, it is just human nature. We expect the locks on our house to keep people out when it is simple to smash a window (or cut a hole in the wall). We are coming around the corner on this one and seeing that we can’t educate everyone and things need to just be more secure by default and leak less information.
  3. People care a lot more about their privacy now. People also don’t realize that most places gathering information don’t care about you as a person, they care about you as a demographic. Granted it is not a happy thought to know how much info about you is floating around but if it personalizes my searches and shows me advertisements for things I am interested in so what? It is only an issue (to me) if that information is used for nefarious purposes.
  4. Many more technologies are shipping with a more “secure by default” mentality. The *nix/bsd attitude has been like this since I can remember and Microsoft has really turned a corner and secured their products. I remember when a new client would tell us they were running an IIS server and we would just laugh, wipe the box, and install FreeBSD/Apache for them. Nowdays I only laugh when people have an Adobe product installed (we all do… so ha ha). Adobe has realized that this is starting to hurt them and are making a big security push like MS did years ago.
  5. Schools have not taught about security and they still don’t. I see a bit of growth in this area but I feel this is incredibly lacking. Every time I give a presentation and ask how many people don’t know about SQL injection someone still raises their hands. It is not acceptable to have developers that don’t even know about the most basic/common security holes and how to prevent them. It is like hiring an electrician that does not know how to use a circuit breaker: they might get by for years without an incident but it is bound to happen eventually.
  6. Phishing/scams/chain letters has risen and fallen a lot. I find most people I talk to realize that people are trying to scam them (or will ask others to see if it is a scam) and that they know if they don’t forward this message to ten other people a kitten will die (except for my sister). 
  7. Piracy became common place. Back in the day it was technically difficult to find the software/music/movies and then crack it if necessary. Now my grandma can run a P2P client (or the vast array of other tools) to get her favorite songs. It is common place and it is sad. Not because I love big rich Hollywood types that complain about the money being stolen from them as they drive through Starbucks in a gold plated Bently. It is the fact that for such a huge market that they continually fail to make it simple to get the content we want quickly, conveniently, and be able to use it how we see fit. If I ran an ice cream store and everyone wanted paint flavored ice cream served off a piece of copper pipe you would see me at the hardware store every day. I think they are starting to get it and I hope to see some progress there so that everyone is happy (except me…. until I get a gold plated Starbucks).
  8. The goal of software development was and still is for the most part to deliver working software. Security takes a huge back seat and is almost never a first class citizen. I don’t see this trend changing much. The nice thing is that many languages are shipping in a more secure configuration which helps developers not leave as many gaping holes but I still feel that education is very important for developers.
Filed Under: General, Security

Integration – Is It Worth It?

Aug 28

One thing I get asked to do a lot is integrate systems with each other or incorporate other systems into one we are currently building. In a lot of scenarios I have been starting to give some pushback on this. Sure integration is cool and all but should it be done?

Expense
The first (and ongoing) issue is the expense of integrating systems. First you have to understand the systems (or at least the APIs being exposed) of each system which can take a lot of time. Secondly we have to write code to integrate the services and adapt concepts from one system to another. This work also needs to be tested and debugged.

Perpetuating The Legacy
The bigger issue I have seen in organizations is that tying a legacy system into your system makes it harder to change or replace the legacy system. If a legacy system has 3-4 systems that depend on it then any changes have to be tested and approved by the consuming systems (expense again).

If we want to replace the legacy system with something better then we have two options. We can either rewrite the system and keep the old API exposed or we can throw it away and force our consumers to change. Rewriting a system and keeping the API may work IF the original API was perfect (or close to perfect). In practice I find that the API is ok but if a person were to rewrite it they could alleviate a lot of the issues and shortcomings discovered over the years. If we do a brand new interface then all our consumers need to change their code which can be…. expensive.

From being in this situation before I have compromised. I created a new system with a better API that was more expressive and simpler to use. I then created a separate project that exposed the old API and translated that to the new API. This does add some performance overhead in translation and lots of things to test (expensive).  It does allow new consumers to use a better API and allowed consumers of the old system to decide if it was worth migrating to the new API.

Integration For Integrations Sake
Many people automatically assume that if the information is in another system that we should integrate the two systems. This does help centralize rules, reduce duplication, and centralize information. This is all true but not always necessary. I would find it acceptable to have some minor duplication if it eliminated a coupling on another system. This is a very careful call to make though as this duplication can lead to duplication of maintainance. Even worse it can lead to their now being two sources of data so when a third system comes along it now consumes both sources for data to try and determine which one is accurate.

One classic example I have is from a client of mine. They have a system that dispatches their vehicles and another system that uses GPS to track their vehicles. They asked for these systems to be integrated as they are always switching between the two. In this case the value of integrating the systems was very low. Instead I recommend that all their operators get two monitors and have both applications open. This is not the 100% perfect solution (unless you are an accountant) but it gets the job done for the right price.

Alternatives
There are ways to integrate but not integrate. One of the simpler ones is to have a button/link/menu item/whatever that fires up a system you would normally integrate with and pass along necessary data. I.e. a button that runs “otherProgram.exe /RunSalesReport 10-10-2009 10-10-2010″ or http://server/SalesReport.aspx?start=10-10-2009&end=10-10-2010. Granted there is a bit of coupling there and some things to maintain but not as much as if we had to call a service, translate the results, and show it on a UI.

Another method is to use manual entry. An example of this would be to use one system to find a product and then type that products manufacture code into your system you are building. Sure it is not as fast and the costs of this slowdown will add up over time but is the cost of integration still higher than the cost it takes for a user to copy/paste a code from one program to another? Not an easy question to answer but one that should be evaluated.

The last method is one typically avoided: double entry. This is where the same (or similar) data is entered into two separate systems. An example of this might be for a sales operation. It may be acceptable for the sales system to have a list of all products, descriptions, and prices of products that they sell. The warehouse system might have its one list of products, dimensions, and inventory levels. As long as when a sale comes in that the order can be filled AND that the sales system does not need to know inventory levels when they make a sale (i.e. if there is none in the warehouse it will just get backordered). This is a very tight line to walk as if an item were entered into one system incorrectly the customer may order 20 Widgets but instead get 20 Gadgets due to the product codes not lining up.

Final Thoughts
I have learned that integration is more expensive than I first thought it would be. I thought that reducing code I had to write would make life easier. It does in some ways but in other ways it adds overhead to development and maintenance. If we just stop and think if it is really necessary to tie two systems together then we might just have a little less coupling and a little more freedom to upgrade some legacy systems. Not integrating is not the only solution…. but neither is integrating.

Filed Under: General, Rants

Learn From My Mistakes?

Aug 21

One of my frustrations with Silverlight has been that the async model is rammed down your throat. I understand the reasoning that it is good to have the UI thread responsive while long running calls are happening. But to me that is something that I code and I control.

The thing that gets me is that there are times where several network operations may have to happen in sequence. Here is a simple contrived example:

var service = new VehicleRentalService();
if (service.AreVehiclesAvailableToRent())
  {
  txtNumberOfCars.Text = service.GetNumberOfCarsForRent();
  if (service.IsTheFlakyOnlineRentalServiceRunning())
      {
       btnBookOnline.Enabled = true;
      }
  }

Now for the above example I would run all this on 1 background thread (leaving the UI nice and responsive) and make sure that I properly delegate the control changes to the UI thread (as controls are not thread safe).

Silverlight forces us to async the calls which leads to a lot of functions that chain together. I find this makes the code a lot harder to read and a lot harder to understand. Here is a hand written rewrite of the above example:

public function Start()
{

var service = new VehicleRentalService();
service.AreVehiclesAvailableToRentCompleted+=VehiclesAvailableToRentResponseRecieved;
service.GetNumberOfCarsForRentCompleted+=NumberOfCarsForRentResponseRecieved;
service.IsTheFlakyOnlineRentalServiceRunningCompleted+=IsTheFlakyOnlineRentalServiceRunningResponseRecieved;

service.AreVehiclesAvailableToRent();

}

public function VehiclesAvailableToRentResponseRecieved(object sender, VehiclesAvailableToRentCompletedEventArgs e)
{
   if (e.Result)
      {
      service.GetNumberOfCarsForRent();
      service.IsTheFlakyOnlineRentalServiceRunning();
     }
}

public function NumberOfCarsForRentResponseRecieved(object sender, NumberOfCarsForRentCompletedEventArgs e)
{
    Dispatcher.BeginInvoke(delegate { txtNumberOfCars.Text = e.Result });
}

public function IsTheFlakyOnlineRentalServiceRunningResponseRecieved(object sender, IsTheFlakyOnlineRentalServiceRunningResponseRecievedCompletedEventArgs e)
{
    Dispatcher.BeginInvoke(delegate { btnBookOnline.Enabled = e.Result });
}

(Some may argue that there should be a GetSystemStatus method on the service that returns all this info to which I would probably agree. For the sake of this post though I am going to run with it).

So the Silverlight code is longer, harder to read, and harder to maintain. It does have the benefit of getting the number of cars for rent and checking if the online booking system is running at the same time which is a nice plus.

For an example a log more complicated than this one I was using a WebRequest to converse with a server in a very back and forth fashion and found that the code quickly became very hard to read so I set about to change things. My idea was to create a class that uses async calls in the background but appear to be synchronous by blocking the caller. i.e.

string customerData = Request.GetResponse(“http://www.dummy.com/getcustomer.aspx”, “CustomerId=1″);
string customerAddress = Request.GetResponse(“http://www.dummy.com/getaddress.aspx”, ParseOutAddressId(customerData));

PLEASE DO NOT USE THIS CODE AS IT DOES NOT WORK (hence the post title):

    public class SyncRequestResponse
    {
        ManualResetEvent _requestCompleted;
        private WebRequest _request;
        private string _postData;
        private Uri _requestUrl;
        private static string _result;

        public string GetResponse(Uri requestUrl, string postData)
        {
            _requestCompleted=new ManualResetEvent(false);
            _requestCompleted.Reset();
            _postData = postData;
            _requestUrl = requestUrl;
            StartRequest();
            _requestCompleted.WaitOne(1000); //block current thread until the response is received or the timeout is reached
            return _result; //the result should be filled now
        }

        private void StartRequest()
        {
            _request = WebRequest.Create(_requestUrl);
            _request.ContentType = “application/x-www-form-urlencoded”;
            _request.Method = “POST”;
            _request.BeginGetRequestStream(GetRequestStreamCompleted, null);
        }

        private void GetRequestStreamCompleted(IAsyncResult result)
        {
                //request stream has returned so fill it
                var content = Encoding.UTF8.GetBytes(_postData);
                var stream = _request.EndGetRequestStream(result );
                stream.Write(content, 0, content.Length);
                stream.Close();
                _request.BeginGetResponse(GetResponseFromRequest, null);
        }

        private void GetResponseFromRequest(IAsyncResult ar)
        {
            var response = _request.EndGetResponse(ar);
            var sr = new StreamReader(response.GetResponseStream());
            _result = sr.ReadToEnd();
            _requestCompleted.Set();
        }
    }

What I quickly found was that the second my WaitOne() line ran was that the background methods would also hang. After a lot of mucking about and some research I found out one very important thing. The WebRequest and WebResponse methods call interacts with the browsers plugin API which runs on…. the UI thread. So by blocking the UI thread it also blocks any calls to the plugin API which blocks my WebRequest methods.

So to solve this I could probably place my sync wrapper onto a background thread to implement the back and forth conversations and then raise an event when it is done but after mucking around it just makes things too complex to read, follow, and maintain. It may still have its uses one day… but it was not as clean as I would like

Solution?
My main issue is when you have async methods that change so for WebRequest calls I decided to inline the callback methods it used. Again it is ugly but I find it simpler to follow a linear action:

public string GetCustomerDataAndBindItToTextBox(Uri requestUrl, string postData)
            {
                var request = WebRequest.Create(requestUrl);
                request.ContentType = “application/x-www-form-urlencoded”;
                request.Method = “POST”;
                request.BeginGetRequestStream(delegate(IAsyncResult result)
                                                   {
                                                       byte[] content = Encoding.UTF8.GetBytes(postData);
                                                       Stream stream = request.EndGetRequestStream(result);
                                                       stream.Write(content, 0, content.Length);
                                                       stream.Close();
                                                       request.BeginGetResponse(delegate (IAsyncResult result2)
                                                                                     {
                                                                                         WebResponse response = request.EndGetResponse(result2);
                                                                                         var sr = new StreamReader(response.GetResponseStream());
                                                                                         this.txtCustomer.Text = sr.ReadToEnd();
                                                                                     }, null);
                                                   }, null);

            }

Filed Under: General

MVVM and Designer Data

Aug 19

Over the last week I have been playing around with Silverlight and the Model View View Model (MVVM) pattern that I have heard such great things about. So far it is a really nice way to separate the UI logic from the UI and make it easily testable.

One of the things I loved in Silverlight was the support for design time data. Design time data allowed you to specify dummy data that would appear in VS/Blend so that you could work with the UI with sample data. This saves so much time as now you don’t have to open the app, (possibly login), navigate to the area you are working on, and then see if you have it the way you want.

The challenge was now to combine MVVM and this dummy design time data. It is a lot simpler than I thought. I simply created a dummy View Model that inherited from my runtime VM and loaded it with sample data.

Runtime ViewModel:
public class SummaryViewModel : BaseViewModel
    {
        public int MoviesOwned { get; set; }
        public int MoviesCurrentlyRentedOut { get; set; }
        public ObservableCollection<Category> Categories { get; set; }

        private readonly MovieServiceClient _service;
        public SummaryViewModel()
        {
            _service = new MovieServiceClient();
            _service.GetAllCategoriesCompleted += GetAllCategoriesCompleted;
            if (!System.ComponentModel.DesignerProperties.IsInDesignTool)            
                _service.GetAllCategoriesAsync();
        }

        private void GetAllCategoriesCompleted(object sender, GetAllCategoriesCompletedEventArgs e)
        {
            Categories = e.Result;
            InvokePropertyChanged(“Categories”);
        }
    }

Design Time View Model:
  public class DesignTimeSummaryViewModelViewModel : SummaryViewModel
    {
        public DesignTimeSummaryViewModelViewModel()
        {
            Categories = new ObservableCollection<Category>();
            Categories.Add(new Category() { Name = “Design Time Test” }); ;
            Categories.Add(new Category() { Name = “Design Time Test 2″ }); ;
            Categories.Add(new Category() { Name = “Design Time Test 3″ }); ;
            MoviesOwned = 10;
            MoviesCurrentlyRentedOut = 5;
        }
    }

Summary.xaml view (designer info in orange, runtime in blue):
<UserControl x:Class=”MovieRental.UI.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
    xmlns:local=”clr-namespace:MovieRental.UI.ViewModels”
    mc:Ignorable=”d”
    d:DesignHeight=”300″ d:DesignWidth=”400″
    d:DataContext=”{d:DesignInstance Type=local:DesignTimeSummaryViewModelViewModel,IsDesignTimeCreatable=True}”

    >
    <UserControl.Resources>

        <local:SummaryViewModel x:Key=”vm” />

    </UserControl.Resources>

    <UserControl.DataContext>

        <Binding Source=”{StaticResource vm}” />

    </UserControl.DataContext>

    <Grid x:Name=”LayoutRoot” Background=”White”>
        <StackPanel>
            <StackPanel Orientation=”Horizontal”>
                <TextBlock Text=”Movies Owned” />
                <TextBlock Text=”{Binding MoviesOwned}” Padding=”7,0,0,0″/>
        </StackPanel>
        <StackPanel Orientation=”Horizontal”>
                <TextBlock Text=”Movies Rented”/>
                <TextBlock Text=”{Binding MoviesCurrentlyRentedOut}” Padding=”7,0,0,0″ />
        </StackPanel>
            <ListBox ItemsSource=”{Binding Categories}” DisplayMemberPath=”Name”>
            </ListBox>
        </StackPanel>
    </Grid>
</UserControl>

So far this is working pretty good. The thing that surprised me is that the designer still runs the runtime ViewModels constructor so I had to put a check in around my WCF call to make sure it did not run in the designer via the      System.ComponentModel.DesignerProperties.IsInDesignTool line of code.

Filed Under: General

A Word Macro To Simplify Resume Generation

Aug 8

I have taken the summer off to look after our kids, get caught up on my todo list (yes it is 2 months long), and do some learning. Now that I am mostly caught up I decided to update my resume but find it hard to remember how many years of experience I have in technologies on my skills matrix. I don’t like sending out a resume that shows what year I started with a technology as that does not accurately represent the number of years of experience. I figured that I could compamise on this and have a master document that has what year I started with a technology and have a vba macro that converts it into years of experience. Here is what I did

  1. Created a new word document with a table in it with 3 columns (column #3 contains the year started) e.g.
    Category Skill Experience
    Languages C# 2003
      VB.NET 2003
      VBA 2010
         
    Database MSSQL 2000
      MYSQL 1999
      Oracle 1 year
  2.  Open up the macro editor (Alt+F11) and added a new module to the project
  3. Put in this code:
    Sub UpdateYears()
        Application.ScreenUpdating = False
        currentYear = Year(Date)
        For Each tbl In ActiveDocument.Tables
            For Each rw In tbl.Rows
                Dim experience As Integer
                If IsNumeric(StripJunk(rw.Cells(3))) Then
                    experience = currentYear - StripJunk(rw.Cells(3))
                    If (experience <= 1) Then
                        rw.Cells(3) = experience & " year"
                    Else
                        rw.Cells(3) = experience & " years"
                    End If
                End If
            Next
        Next
    End Sub
    Private Function StripJunk(ByVal s As String)
      StripJunk = Trim(Replace(s, vbCr & Chr(7), ""))
    End Function
  4. Saved my word document as “Word macro-enabled document *.docm”
  5. Ran the macro (in office 2010->click “view” on the ribbon. Then click the macro drop down. Then click “View Macros”. Run the UpdateYears macro
  6. Save a copy of the document as a regular word doc without the macros and send it off.

Hopefully this saves you a few hours of VBA/Macro headaches!

Filed Under: General

Going Digital At Home – Part 4 – Digitization Of Media

Aug 3

The most painful and time consuming part of this project has been digitizing our DVD collection. I thought it would be as simple as downloading a program and rip it is done…. not so much in the end. Most mainstream companies are avoiding the area of DVD digitization due to potential issues of the legality of ripping DVDs. Another issue came down to encoding support in the software I tried (most were doing h.246) which would not play on some of my lower powered devices. The other issue is that there are SO many options and settings to tweak that it takes a long time to get them just right. I started ripping only one chapter of a movie and then watching that on different devices and then tweaking settings.

To start with there are many different ways to digitize your DVDs. The first thing I tried was using VLC media player which (unkown to me) has an option to save a DVD to disk. I found that most outputs it put out was distorted and had lots of green blocks all over. I also tried DVDFab which I could not get the quality I wanted and it was trial software. Handbrake is another popular software but it does not do decryption so you have to install other software (I triewantd AnyDVD which worked awesome) in combination with Handbrake. Handbrake only supported H.246 or MPEG4 and I found the MPEG4 quality was too low (and I could not seem to get it any better).

What I finally got to work is a two step process. The first step was to rip the contents of the DVD to a VOB file using DVDDecryptor which takes about 20 minutes. A VOB file is the raw video/audio/subtitiles from the disk which some programs can read in and convert. The next step was to feed the VOB into a program called MeGUI which is a UI wrapper around AviSynth that works quite well. I found it takes 2-3 hours to encode a video using MeGUI.

Now if you have a lot of movies then you need some automation to this process. What I did was gather up 5 spare DVD roms and combined them into a computer so I could backup 5 DVDs at a time. I then wrote a bit of code (I may publish it later) that starts DVDDecryptor on the command line, rips the disk, ejects the disk, then monitors for a new disk. This allowed me to just walk by and see the ejected trays and then insert new disks which worked well. My big issue was that the raw DVD is about 5 GB so you can fill up storage quick so I moved a lot of the raw files to other computers as the drive on my ripping computer filled up.

Once I had my movies ripped (or my hard drives filled) it was time to compress them down to save some space using MeGUI+Avisynth. When you install the software it asks if you want to download some presets which I did. In the end I used XVid-Balanced to do my encoding. Then I used the one click encoding tool in MeGUI and queued up all my VOB files. As this process takes 2-3 hours (depending on CPU power) I ran it on multiple computers. Many of my computers are multi-core and MeGUI has the option to spin up multiple worker threads but I found that it crashed so I just ran one worker (which still used multiple cores).

Filed Under: General