<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Ivan Zlatev</title>
        <description>Writing about leadership, management, emotional resiliency, software engineering, tech, gadgets.</description>
        <link>http://ivanz.com</link>
        <atom:link href="http://ivanz.com/feed.xml" rel="self" type="application/rss+xml" />
        
            <item>
                <title>How to disable the Sign in with Google pop-up across web sites</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I’ve gotten tired of all those “Sign in with Google” pop-ups, especially the bad/overly aggressive implementations that do it in every new tab branch opened of the same page (looking at you TripAdvisor), so here is how to remove it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2024-11-13-how-to-disable-google-sign-in-popup-on-sites/image-3.png&quot; alt=&quot;bye bye&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;steps-for-web&quot;&gt;Steps for Web&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Install your favourite ad blocker (e.g. I use &lt;a href=&quot;https://ublockorigin.com/&quot;&gt;uBlock Origin&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Add the following custom rule and you are done:&lt;/p&gt;

    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||accounts.google.com/gsi/*&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;steps-for-android-apps&quot;&gt;Steps for Android apps&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;My Account&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security&lt;/code&gt; (&lt;a href=&quot;https://myaccount.google.com/security&quot;&gt;link&lt;/a&gt;)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Scroll down to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Your connections to third-party apps and services&lt;/code&gt; and click on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;See all connections&lt;/code&gt;&lt;/strong&gt;
  &lt;img src=&quot;/content/2024-11-13-how-to-disable-google-sign-in-popup-on-sites/image-2.png&quot; alt=&quot;connections bit&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Click on the gear/cog icon:&lt;/strong&gt;
 &lt;img src=&quot;/content/2024-11-13-how-to-disable-google-sign-in-popup-on-sites/image-1.png&quot; alt=&quot;cog image&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Turn off the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sign in prompts&lt;/code&gt; toggle and you’re done (&lt;a href=&quot;https://myaccount.google.com/connections/settings&quot;&gt;direct link&lt;/a&gt;)&lt;/strong&gt;
 &lt;img src=&quot;/content/2024-11-13-how-to-disable-google-sign-in-popup-on-sites/image.png&quot; alt=&quot;toggle&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                
                            <pubDate>Wed, 13 Nov 2024 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2024/11/13/how-to-disable-google-sign-in-popup-on-sites?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2024/11/13/how-to-disable-google-sign-in-popup-on-sites?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>13 Emotional Resilience Challenges in Engineering Leadership and Management + Tips</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;This is a rather long post as it captures the 13 days of lessons learnt and tips I’ve been sharing on &lt;a href=&quot;https://www.linkedin.com/in/ivanzlatev/&quot;&gt;LinkedIn&lt;/a&gt;. Definitely interested to hear other’s experiences and thoughts, so do drop me a comment below, if you feel like it.&lt;/p&gt;

&lt;p&gt;The content here is predominantly aimed at new managers and leaders as well as new managers of managers, but hopefully others can benefit too.&lt;/p&gt;

&lt;h2 id=&quot;1-feedback-loops-become-slower-and-it-takes-longer-to-see-the-impact-of-your-decisions-and-actions-which-can-create-self-doubt-and-insecurity-creep&quot;&gt;1. Feedback loops become slower and it takes longer to see the impact of your decisions and actions, which can create self-doubt and insecurity creep&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Ensure you have measurable definition of success in place for yourself and that you refer to it.&lt;/li&gt;
  &lt;li&gt;Set clear goal and expectations for what you are focusing on and make sure that you have either reliable qualitative or quantitative way to measure progress and success&lt;/li&gt;
  &lt;li&gt;Rock your own feedback and actively seek feedback and don’t wait until your performance review time. Be aware that due to the position of authority (depending on environmental/cultural factor as well), the quality and quantity of constructive feedback may decrease.&lt;/li&gt;
  &lt;li&gt;Grow your introspective and reflective skills to self-troubleshoot and expand your mindset and perspectives.&lt;/li&gt;
  &lt;li&gt;Ensure you have a supporting structure in place, such as a mentor and coach.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2-context-switching-increases-by-factor-of-n-in-terms-of-volume-frequency-and-types-which-can-be-disorienting-and-overwhelming&quot;&gt;2. Context switching increases by factor of N in terms of volume, frequency and types, which can be disorienting and overwhelming&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Learn to identify what brain power and energy types you are using in different contexts and optimize your schedule around that. You may need to grow your self-awareness skills through mindfulness practice (e.g. meditation). Keep experimenting. You may find that meetings work best for you in the morning or maybe that focus time works best for you in the morning and so on.&lt;/li&gt;
  &lt;li&gt;Allocate regular focus time for yourself - your brain has limits. Block it off in your diary and guard it like it’s a precious stone. Accept that you won’t always be able to hold on to all of it as things may crop up, but do your best. You may find that having a bit of quiet time at the start and end of each day will help you prep and digest.&lt;/li&gt;
  &lt;li&gt;Do reset your calendar every now and then to defragment as things creep in.&lt;/li&gt;
  &lt;li&gt;Companies tend to have a heartbeat and a level of predictability associated with - learn to identify that and use it to your advantage as to how you plan your day and weeks. In a start-up that would be adrenaline pumped heart with low predictability, but as the company gets larger there will be times where certain things happen and activity escalates (e.g. performance reviews, quarterly planning).&lt;/li&gt;
  &lt;li&gt;Look for delegation, and thus sponsorship, opportunities at all times.&lt;/li&gt;
  &lt;li&gt;Give your brain time to adapt - it’s awesome like this.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;3-you-may-feel-less-part-of-a-team-which-will-affect-your-sense-of-belonging-and-can-leave-you-feeling-lonelier-than-before&quot;&gt;3. You may feel less part of a team, which will affect your sense of belonging and can leave you feeling lonelier than before&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Accept that the moment you step into a position of authority it changes the relationship dynamics. This is something a new manager will start facing, especially if they are doing the transition in the team where they have been an individual contributor before.&lt;/li&gt;
  &lt;li&gt;A bigger step-change for this is becoming manager of managers, so be mindful as you do make that transition.&lt;/li&gt;
  &lt;li&gt;Avoid isolating yourself - it will leave you feeling alone with your challenges and increase your stress levels. Instead look to connect with other peers in the company doing the same job and outside (e.g. join meetups and so on).&lt;/li&gt;
  &lt;li&gt;Make sure you have someone to talk to with whom you feel safe to share with (mentor, coach)&lt;/li&gt;
  &lt;li&gt;Deliberately invest in building better relationships at work&lt;/li&gt;
  &lt;li&gt;Take care of yourself outside of work socially and community-wise. It can be easy for work to become the sole source of sense of belonging, which is not a healthy dynamic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;4-the-volume-of-information-that-you-have-exposure-to-may-increases-dramatically-in-both-depth-and-breadth-which-will-feel-overwhelming-at-times&quot;&gt;4. The volume of information that you have exposure to may increases dramatically in both depth and breadth, which will feel overwhelming at times&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Your brain will adjust over time and will learn how to filter it and what to capture. Perhaps you will experiment and pick up some tools/techniques in the process.&lt;/li&gt;
  &lt;li&gt;Make conscious deliberate decisions about what information you need vs want and why. The temptation to over-consume information to ‘stay on top of things’ (sense of control) is dangerous, so be strategic about it as a means to be tactical about your limited time, energy and brain capacity.&lt;/li&gt;
  &lt;li&gt;Every time you make a step change in leadership reset your expectations and re-review regularly your information needs. Give yourself time and space to figure it out over time.&lt;/li&gt;
  &lt;li&gt;Avoid being overly reactive to new information and apply self-control over the urge to explore/act on it unless needed.&lt;/li&gt;
  &lt;li&gt;Learn to let go and live in an imperfect world where you can only focus on what’s on N things at a time.&lt;/li&gt;
  &lt;li&gt;Accept that you will start getting exposed to information that you may not understand fully, so sometimes focus less on the information itself, but the thought processes and approaches behind it. Use coaching and curious questioning. Build trust.&lt;/li&gt;
  &lt;li&gt;Develop your people’s communication skills, so that information is presented at the right level of detail given the context its needed. Give peers feedback on such.&lt;/li&gt;
  &lt;li&gt;Make sure to allocate time and space to give yourself a chance to process and reflect.&lt;/li&gt;
  &lt;li&gt;Build a support structure for your self - peer community, coach, mentor. Learn how others are doing things.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;5-the-general-level-of-uncertainty-and-ambiguity-will-rapidly-increase-which-may-leave-your-feeling-anxious-scared-and-out-of-control&quot;&gt;5. The general level of uncertainty and ambiguity will rapidly increase which may leave your feeling anxious, scared and out of control&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;For new engineering managers it can be a big challenge emotionally, because there is no replacement for the predictability and early validation possible in the software development cycle (write code -&amp;gt; validate it works -&amp;gt; ship it to production). There are also no quick fixes after something goes “live”.&lt;/li&gt;
  &lt;li&gt;Accept that with every leadership step-change it will feel like uncertainty will increase - in part because it’s an entirely new role, but also because there will be more moving pieces and more people involved in the execution.&lt;/li&gt;
  &lt;li&gt;Avoid succumbing to the need for control, which is a natural tendency of the anxiety that comes and accept that you will simply not ever be in control. Adding more process, diving deeper into details to assure yourself is common action, but is a good recipe for burnout and dissatisfaction on the other side of it.&lt;/li&gt;
  &lt;li&gt;Avoid over-thinking and looking for perfection in decisions.&lt;/li&gt;
  &lt;li&gt;Accept that thing will go wrong - it’s simply a matter of fact. The best learnings come from failure (do we even learn anything when we succeed?)&lt;/li&gt;
  &lt;li&gt;Focus on iterating on your ability to set clear expectations, communicate constrains.&lt;/li&gt;
  &lt;li&gt;Learn to build trust, to let go and to build the right framework for you to have a “good enough” confidence and comfort with things, without over-indexing on reactivity due to the emotional impact of uncertainty.&lt;/li&gt;
  &lt;li&gt;When you feel out of control, take a deep breath and re-focus on what you are in control of and deliberately let go of what you can’t. Don’t bottle that tension and stress up.&lt;/li&gt;
  &lt;li&gt;Try some mindfulness practice to build emotional resiliency in what may seem like high pressure situations.&lt;/li&gt;
  &lt;li&gt;Get someone to talk to - a coach, a mentor, peers. The worst thing you can do for yourself is be overwhelmed alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;6-the-mistakes-that-you-make-will-have-more-impact-than-before-which-can-increase-the-level-of-fear-anxiety-and-internal-pressure-to-get-things-right&quot;&gt;6. The mistakes that you make will have more impact than before, which can increase the level of fear, anxiety and internal pressure to get things “right”&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Watch out for the fear of failure causing anxiety, vulnerability, and behaviour such as perfectionism, overthinking, etc. Improve your mindfulness skills to pick it up.&lt;/li&gt;
  &lt;li&gt;Accept that you will make mistakes. It’s not a question of if, but more of a question of when. At the end of the day, we are all human and as such we are flawed in many ways, so mistakes are part of our nature.&lt;/li&gt;
  &lt;li&gt;Accept that you will fail. It’s a question of when, not if. Failure is hard emotionally, but is the best source of learning. Do we even learn from success?&lt;/li&gt;
  &lt;li&gt;Identify your tolerance for acceptable risk and play around with stretching it.&lt;/li&gt;
  &lt;li&gt;Do accept and acknowledge all the uncomfortable feelings that come with this - it will help build your tolerance, thus emotional resilience to them.&lt;/li&gt;
  &lt;li&gt;Sanity check your emotions with some introspective questions, such as “What is the worst that will happen?”&lt;/li&gt;
  &lt;li&gt;Swich from “What if “ type of thinking to “How will I handle”, but try to avoid getting into overthinking spirals. As you will learn, with time, there is no “right decision” - you can simply optimize for what you know at the time, hope for the best and believe that you will be able to deal with the consequences.&lt;/li&gt;
  &lt;li&gt;Avoid working in toxic company culture, where failure and mistake is a dirty word.&lt;/li&gt;
  &lt;li&gt;Use data to evaluate options and decisions.&lt;/li&gt;
  &lt;li&gt;Don’t let your ego (bruised or not) to get in the way of recognising mistakes and failure. Have you seen mistakes being swept under the carpet by leaders before? It’s important to be honest, transparent and exercise humility and vulnerability when it happens and focus on the learnings and moving forward. Be real.&lt;/li&gt;
  &lt;li&gt;Build yourself a support structure around you (manager, mentor, peers)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;7-your-sense-of-achievement-and-impact-may-take-a-hit-which-can-create-dissatisfaction-creep-and-can-affect-your-confidence&quot;&gt;7. Your sense of achievement and impact may take a hit, which can create dissatisfaction creep and can affect your confidence.&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;This is very relevant for new engineering managers who are transitioning from doing to enabling/supporting/empowering/facilitating/etc. This is because up until this point the sense of achievement is likely based (and measured) on direct impact made through output (e.g. code), whereas now the impact be less indirect and there will be a sense of lack of be output “to show for it”.&lt;/li&gt;
  &lt;li&gt;This can be an even harder transition, when a manager becomes a manager of managers and thus steps out of the team that is delivering the impact.&lt;/li&gt;
  &lt;li&gt;It’s normal - it’s an adjustment of how you measure you worth and value-add as part of the role transition you are going through. It can take time as it’s a mindset shift and your brain will need time to rewire.&lt;/li&gt;
  &lt;li&gt;Re-think and redefine what you see as “win” and “impact” for yourself. Train your brain to start notice even the smallest of wins. Be your own cheerleader.&lt;/li&gt;
  &lt;li&gt;Avoid self-lowering thinking such as “I am not being useful or not adding value”. There might be times where indeed you are not adding value to your teams as they are self-sufficient, so be mindful and aware when to refocus your time between types of focus.&lt;/li&gt;
  &lt;li&gt;Accept that feedback loops are longer and thus it may take time to see the impact of your actions, so aim to set yourself measurable goals and get regular feedback.&lt;/li&gt;
  &lt;li&gt;Watch out for your need for creativity and keeping your creative self fulfilled too. This will affect different people at different intensity. Find something ‘yours’ and focus on it, when you have time. Alternatively look to rebalance outside of work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;8-your-sense-of-expertise-will-erode-and-morph-over-time-which-can-challenge-your-sense-of-competency-and-result-imposter-syndrome&quot;&gt;8. Your sense of expertise will erode and morph over time, which can challenge your sense of competency and result imposter syndrome&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;It’s important to acknowledge that - the sooner the better. Every time you make a step change in leadership you are going into a new role. And surprise, surprise the goal is not to be an expert in your past role any more, so watch out not to act like one.&lt;/li&gt;
  &lt;li&gt;As you make step changes up the leadership ladder, some of your powers (e.g. ‘knowledge’) will diminish, but some others will grow (e.g. influencing). However, there may be a temporary period where you feel the disbalance and it may be frustrating until you hit the rebalancing sweet spot.&lt;/li&gt;
  &lt;li&gt;Managing someone in a role that you were very recently (e..g managing a manager when you were a manager recently) can trigger all sorts of insecurities if you don’t focus on nurturing your growth mindset. For example you may feel inadequate because you suddenly realize the way you did something before was not very good when you compare yourself/your approach to someone you manage. But, actually that’s awesome - you have just learnt something new, but also identified someone that’s very good at something that you can lean on.  It’s all about perspectives. Also in general comparing yourself with others is no good anyway, so avoid in general.&lt;/li&gt;
  &lt;li&gt;Watch out for assuming that you should have a right answer and even an answer to questions that hit you by direct reports. You can’t possibly have all the answers and assuming this so will erode your confidence and competency perception, which in turn will fill you with guilt and voila - imposter syndrome. Build some coaching skills and find mentors for your direct reports for areas they need, where you can’t support them directly.&lt;/li&gt;
  &lt;li&gt;Be humble and learn. Ego is the enemy here.&lt;/li&gt;
  &lt;li&gt;If you care about this, a wonderful way to maintain some level of expertise is to learn from others and the output of others in the company and outside (e.g. system designs/RFC that are being produced by teams). Asking lots of questions in a curious way and being upfront what you want to get out of it (e.g. not interrogating/challenging) can be helpful too. Going to conferences and meetups is another way.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;9-having-an-increased-scope-of-accountability-can-put-more-internal-and-external-pressure-increasing-your-stress-levels&quot;&gt;9. Having an increased scope of accountability can put more internal and external pressure, increasing your stress levels&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Your emotional resilience will build up over time, but it’s absolutely critical to take good care of yourself at all times and find ways to cope with stress, anxiety, etc.&lt;/li&gt;
  &lt;li&gt;Focus on growing people internally and hiring so that you can delegate and grow other leaders, whilst sharing the load to create sustainability&lt;/li&gt;
  &lt;li&gt;Focus on improving your expectation management, communication, time management, prioritization, delegation skills.&lt;/li&gt;
  &lt;li&gt;There are various tools out there that can help you evaluate your accountabilities and responsibilities and evaluate where the priority of your energy-spent should be. Ask your peers, your manager for opinions as well, where is your time and energy best spent as you may end up making the wrong assumptions.&lt;/li&gt;
  &lt;li&gt;Learn to say no constructively, when needed - it’s a skill.&lt;/li&gt;
  &lt;li&gt;Find a mentor and a coach to support you&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;10-supporting-and-working-with-an-increased-number-of-people-direct-reports-skip-level-reports-etc-will-have-a-toll-on-you-emotionally&quot;&gt;10. Supporting (and working with) an increased number of people (direct reports, skip-level reports, etc) will have a toll on you emotionally&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Your emotional resilience will build up over time naturally as you get exposed to more scenarios and situations, but it’s super duper mega important to take care of yourself meanwhile. Whilst it’s easy to say “take care of yourself”, it can be harder to achieve as leadership can put you in a new place in life and how to do that may be non-obvious.&lt;/li&gt;
  &lt;li&gt;Coaching and mentoring skills can help you turn what would be situations ending up with emotional baggage to situations, which end up with no baggage and positive forward momentum.&lt;/li&gt;
  &lt;li&gt;Build self-awareness (e.g. through mindfulness practice and skill building) skills to help you improve your Emotional Intelligence and help you regulate and manage your emotional state better.&lt;/li&gt;
  &lt;li&gt;Build self-troubleshooting skills, such as introspection, reflective writing to help you train your brain and build a mindset of seeing things the same experience from different perspectives and angles.&lt;/li&gt;
  &lt;li&gt;Be clear with yourself what your values are as this will help you identify and acknowledge internal (in yourself) and external (with others) emotional conflict and thus work with it.&lt;/li&gt;
  &lt;li&gt;Get a coach and a mentor. Don’t shy away from working on a deeper level, if needed, with a psychologist/psychotherapy professional as well - working with other people can be a great way to retrigger any relational or other traumas, or simply old unresolved experiences from your past whether you are aware of it or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;11-it-can-be-hard-to-say-no-andor-disappoint-people&quot;&gt;11. It can be hard to say no and/or disappoint people&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Hard truth of leadership is that you will not liked by everyone and your job is not to please everyone, so the sooner you get comfortable with that - the better.&lt;/li&gt;
  &lt;li&gt;Avoid taking ownership ownership or responsibility for the emotional responses of people (e.g. disappointment, frustration, dissatisfaction) as this will lead to unnecessary sticky guilt and feeling bad about stuff (and associated fear of letting them down due to ownership taken). Do maintain a curious mindset and perhaps help them reframe and evaluate things for themselves from different perspectives.&lt;/li&gt;
  &lt;li&gt;Try to reframe personalization thinking (“I am disappointing them”) to de-personalized (the situation, circumstance, decisions and outcomes thereof. And no - I am not suggesting you do that when you need to own up to a mistake you’ve made, which is often people that don’t own their mistakes do, which in turn leads to double the erosion of trust.&lt;/li&gt;
  &lt;li&gt;Never leave space for assumptions (for both yourself and them) - be honest and direct, even if very uncomfortable. Learn to be uncomfortable, accept it and cherish it - it means you are growing emotionally.&lt;/li&gt;
  &lt;li&gt;Don’t internalize organizational limitations (aka circumstantial/situational limitations), which are negatively impacting people, as a personal failure (e.g. redundancies, teams becoming anaemic due to attrition, etc). Identify what’s within your control and influence and what isn’t as you don’t want to get sticky feelings of powerlessness/disempowerment, which will unnecessarily affect your confidence.&lt;/li&gt;
  &lt;li&gt;Consider that what on the surface may seem negative, can actually be very positive when looked from different angles. E.g. delivering uncomfortable constructive feedback that may affect the other person emotionally may be tough, but it will be helpful for their growth. Letting go someone from a team may be helpful for the team and for them to find a better fit place, etc. Not having someone promoted might save them from difficult times if they weren’t ready yet.&lt;/li&gt;
  &lt;li&gt;Practice and even do some role play with someone if that helps. Saying no and delivering hard messages is a skill.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;12-when-people-you-manage-leave-it-can-create-self-doubt-and-insecurity&quot;&gt;12. When people you manage leave, it can create self-doubt and insecurity&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Don’t overthink it and make assumptions and focus on the facts and what you know and what your data points are telling you (e.g. feedback).&lt;/li&gt;
  &lt;li&gt;Remember that people are empowered to make a choice for what’s right for them and that’s a good thing.&lt;/li&gt;
  &lt;li&gt;Focus on the positives - often people will leave, because they have had a chance to learn and grow and have decided to move on to the next thing and use what they have learnt. Or it could be because they have found a place that they will earn more money, get more challenge, and so on and that’s good for them. Most of the time someone leaving can be quite positive, even if it creates practical pains&lt;/li&gt;
  &lt;li&gt;Focus on having a solid succession plan in place to reduce the practical pain of people leaving.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;13-you-will-be-swimming-in-new-and-unfamiliar-territory-a-lot-of-the-time-and-this-can-make-you-feel-vulnerable&quot;&gt;13. You will be swimming in new and unfamiliar territory a lot of the time and this can make you feel vulnerable&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Vulnerability, when acknowledged, can be very uncomfortable. Even acknowledging it can be hard as it may go against the brain’s self-preservation instincts. It may take building some mindfulness skills and reducing your emotional reactivity and increasing your tolerance to the feeling get there.&lt;/li&gt;
  &lt;li&gt;Embrace the feelings that come with vulnerability and don’t try to run way as that will only result compensatory/defensive behaviours, which are probably the wrong thing to do (e.g. micromanaging, too much process, etc)&lt;/li&gt;
  &lt;li&gt;Don’t jump too quickly into conclusions and actions - check-in on your motivations.&lt;/li&gt;
  &lt;li&gt;Ego is the enemy as it aims to protect our vulnerable self and thus deny us the humble growth mindset.&lt;/li&gt;
  &lt;li&gt;Vulnerability is powerful and not a weakness, as when your emotional tolerance to it is built up it can empower you in many different ways.&lt;/li&gt;
&lt;/ul&gt;
</description>
                
                            <pubDate>Thu, 24 Nov 2022 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2022/11/24/13-emotional-resilience-leadership-lessons-and-tips?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2022/11/24/13-emotional-resilience-leadership-lessons-and-tips?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>MSpec (Machine Specifications) support for .csproj-based .NET Core projects now available</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I am pleased to announce that it is now possible to use and run &lt;a href=&quot;https://github.com/machine/machine.specifications&quot;&gt;Mspec (Machine Specification) tests&lt;/a&gt; when using .csproj based .NET Standard / .NET Core projects including  multi-targeting scenarios.&lt;/p&gt;

&lt;p&gt;The runner (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Machine.Specifications.Runner.VisualStudio&lt;/code&gt; nuget package) supports:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet test&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Visual Studio’s Test Explorer&lt;/li&gt;
  &lt;li&gt;vstest.console&lt;/li&gt;
  &lt;li&gt;Visual Studio Team Services and TFS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For information on how to migrate from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csproj&lt;/code&gt;-based mspec tests please refer to &lt;a href=&quot;https://github.com/machine/machine.specifications/wiki/.NET-Core-%28.NET-CLI%29&quot;&gt;this wiki page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another news is that Machine.Fake 2.8.0 is now also available with .NET Core (.NET Standard) support for Moq, FakeItEasy and NSubstitute.&lt;/p&gt;

&lt;p&gt;Here is an example .csproj targeting both .NET Core 1.1 and .NET Framework 4.6:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;    
    &amp;lt;TargetFrameworks&amp;gt;netcoreapp1.1;net46&amp;lt;/TargetFrameworks&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include=&quot;Machine.Specifications&quot; Version=&quot;0.11.0&quot; /&amp;gt;
    &amp;lt;PackageReference Include=&quot;Machine.Specifications.Runner.VisualStudio&quot; Version=&quot;2.*&quot; /&amp;gt;
    &amp;lt;PackageReference Include=&quot;Microsoft.NET.Test.Sdk&quot; Version=&quot;15.*&quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Example output:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\code\mspec-test-sample\MSpecSampleSolution\Sample&amp;gt;dotnet test
Build started, please wait...
Build completed.

Test run for C:\code\mspec-test-sample\MSpecSampleSolution\Sample\bin\Debug\netcoreapp1.1\MSpecSample.dll(.NETCoreApp,Version=v1.1)
Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
Machine Specifications Visual Studio Test Adapter - Executing Specifications.
Machine Specifications Visual Studio Test Adapter - Executing tests in C:\code\mspec-test-sample\MSpecSampleSolution\Sample\bin\Debug\netcoreapp1.1\MSpecSample.dll
Complete on 1 assemblies

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 0.8338 Seconds


Test run for C:\code\mspec-test-sample\MSpecSampleSolution\Sample\bin\Debug\net46\MSpecSample.dll(.NETFramework,Version=v4.6)
Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
Machine Specifications Visual Studio Test Adapter - Executing Specifications.
Machine Specifications Visual Studio Test Adapter - Executing tests in C:\code\mspec-test-sample\MSpecSampleSolution\Sample\bin\Debug\net46\MSpecSample.dll
Complete on 1 assemblies

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 0.7364 Seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
                
                            <pubDate>Fri, 17 Mar 2017 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2017/03/17/mspec-dotnet-test-csproj-support-available?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2017/03/17/mspec-dotnet-test-csproj-support-available?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>New features and improvements coming to C# in Visual Studio Code</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Visual Studio Code is my editor of choice (even) for C#/.NET (unless I need to do some serious refactoring or software archeology exercise in the Visual Studio IDE with ReSharper). I’ve noticed a couple of opportunities for imporovements in the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp&quot;&gt;C# extension&lt;/a&gt; (&lt;a href=&quot;https://github.com/OmniSharp/omnisharp-vscode&quot;&gt;GitHub&lt;/a&gt;) and a couple of merged pull requests all of the below updates are now available in the latest 1.4 beta of the C# extension and will land in the next release.&lt;/p&gt;

&lt;h2 id=&quot;new-navigate-and-view-code-of-symbols-for-which-source-code-is-unavailable&quot;&gt;New: Navigate and view code of symbols for which source code is unavailable&lt;/h2&gt;

&lt;p&gt;The ability to dive into the structure of any type even such without source code was a major feature I missed in Visual Studio Code when working with a lot of third party dependencies. Now it’s here and supported are both “Go to definition” as well as “Peek Definition”:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/goto-reference.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/peek-reference.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;new-c-6-expression-bodied-members-syntax-highlighting&quot;&gt;New: C# 6 Expression bodied members syntax highlighting&lt;/h2&gt;

&lt;h3 id=&quot;before&quot;&gt;Before&lt;/h3&gt;

&lt;p&gt;Note how the last declaration used to break the highlighting:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/ex-before.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;after&quot;&gt;After&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/ex-after.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;improved-namespace-and-usings-syntax-highlighting&quot;&gt;Improved: Namespace and usings syntax highlighting&lt;/h2&gt;

&lt;h3 id=&quot;before-1&quot;&gt;Before&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/ns-before.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;after-1&quot;&gt;After&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/ns-after.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;improved-method-parameters-highlighting&quot;&gt;Improved: Method parameters highlighting&lt;/h2&gt;

&lt;h3 id=&quot;before-2&quot;&gt;Before&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/arg-before.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;after-2&quot;&gt;After&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/arg-after.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fixed-reserved-word-highlighting-class-etc&quot;&gt;Fixed: Reserved word highlighting (@class, etc)&lt;/h2&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@class&lt;/code&gt; used to break the highlighting for example in this case:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2016-08-18-visual-studio-code-csharp-improvements/reserved-kw.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Thu, 18 Aug 2016 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2016/08/18/visual-studio-code-csharp-improvements?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2016/08/18/visual-studio-code-csharp-improvements?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Announcing Machine.Specifications (MSpec) 0.11 for .NET Core, .NET CLI and .NET Standard</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I am delighted to announce that &lt;a href=&quot;https://github.com/machine/machine.specifications/wiki&quot;&gt;MSpec&lt;/a&gt; (Machine.Specifications) is now available for .NET Standard 1.3+ together with a new .NET CLI (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet test&lt;/code&gt;) test runner for .NET Core and .NET 4.5+.&lt;/p&gt;

&lt;p&gt;If you are not sure what MSpec is - scroll down for a quick intro. In short it’s a “context/specification” test framework.&lt;/p&gt;

&lt;p&gt;This is backwards compatible version, so there shouldn’t be any issues using this version with ReSharper, CodeRush or other test runners when targeting the .NET Framework.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Package&lt;/th&gt;
      &lt;th&gt;Version&lt;/th&gt;
      &lt;th&gt;NuGet&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;dotnet-test-mspec&lt;/td&gt;
      &lt;td&gt;0.2.0&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.nuget.org/packages/dotnet-test-mspec&quot;&gt;NuGet&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Machine.Specifications&lt;/td&gt;
      &lt;td&gt;0.11.0&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.nuget.org/packages/Machine.Specifications&quot;&gt;NuGet&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Machine.Specifications.Should&lt;/td&gt;
      &lt;td&gt;0.11.0&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.nuget.org/packages/Machine.Specifications.Should&quot;&gt;NuGet&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Machine.Fakes&lt;/td&gt;
      &lt;td&gt;2.8.0-beta3&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.nuget.org/packages/Machine.Fakes/2.8.0-beta3&quot;&gt;NuGet&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Machine.Fakes.Moq&lt;/td&gt;
      &lt;td&gt;2.8.0-beta3&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.nuget.org/packages/Machine.Fakes.Moq/2.8.0-beta3&quot;&gt;NuGet&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Machine.Fakes.Moq is in beta due to the underlying Moq dependency not having yet a stable release for .NET Standard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/machine/machine.specifications/wiki&quot;&gt;MSpec documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/machine/machine.specifications/issues&quot;&gt;MSpec issue tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;getting-started-on-net-core-and-net-cli&quot;&gt;Getting started on .Net Core and .NET CLI&lt;/h2&gt;

&lt;p&gt;Here is an example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; of a tests project which targets both .NET Core and .NET 4.5. As you can see it includes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Dependency on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Machine.Specifications&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet-test-mspec&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;testRunner&quot;: &quot;mspec&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;project.json&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;testRunner&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;mspec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;frameworks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;net45&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;netcoreapp1.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Microsoft.NETCore.App&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1.*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;platform&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;FluentAssertions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;4.12.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Machine.Specifications&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0.11.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dotnet-test-mspec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can now use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet test&lt;/code&gt; to run the tests:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; dotnet test

Project Example (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.

dotnet-test-mspec: 0.2.0
Machine.Specifications: 0.11.0.0
Specs in Example:
...***

Contexts: 3, Specifications: 6, Time: 0.13 seconds
  3 passed, 0 failed, 3 not implemented

Project Example (.NETFramework,Version=v4.5) was previously compiled. Skipping compilation.

dotnet-test-mspec: 0.2.0
Machine.Specifications: 1.0.*
Specs in Example:
...***

Contexts: 3, Specifications: 6, Time: 0.09 seconds
  3 passed, 0 failed, 3 not implemented

SUMMARY: Total: 2 targets, Passed: 2, Failed: 0.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;known-issues-with-the-dotnet-cli-dotnet-test-runner&quot;&gt;Known Issues with the dotnet cli (dotnet test) runner&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;IDE integration (aka Design-Time) is not yet implemented, so you won’t be able to see or run test in Visual Studio IDE: &lt;a href=&quot;https://github.com/machine/machine.specifications/issues/303&quot;&gt;#303&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The console output format doesn’t have colours and enough new line padding, etc. This is an upstream issue with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet test&lt;/code&gt; and hopefully will be fixed in the next preview. &lt;a href=&quot;https://github.com/machine/machine.specifications/issues/311&quot;&gt;#311&lt;/a&gt;. This is potentially blocking the TeamCity and AppVeyor auto-detect outputs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hopefully they should land in v0.3 of the test runner.&lt;/p&gt;

&lt;h2 id=&quot;what-is-mspec&quot;&gt;What is MSpec?&lt;/h2&gt;

&lt;p&gt;MSpec is called a “context/specification” test framework because of the “grammar” that is used in describing and coding the tests or “specs”. That grammar reads roughly like this&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When the system is in such a state, and a certain action occurs, it should do such-and-such or be in some end state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You should be able to see the components of the traditional Arrange-Act-Assert model in there. To support readability and remove as much “noise” as possible, MSpec eschews the traditional attribute-on-method model of test construction. It instead uses custom .NET delegates that you assign anonymous methods and asks you to name them following a certain convention.&lt;/p&gt;

&lt;p&gt;You can read more about MSpec &lt;a href=&quot;https://github.com/machine/machine.specifications/wiki&quot;&gt;in the docs here&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Authentication&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;When_authenticating_an_admin_user&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Establish&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SecurityService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;Because&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Token&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Authenticate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;It&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should_indicate_the_users_role&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ShouldEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Roles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Admin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;It&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should_have_a_unique_session_id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SessionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ShouldNotBeNull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SecurityService&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserToken&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and an example of Machine.Fakes usage in MSpec:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Authentication&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;When_authenticating_an_admin_user&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WithFakes&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Establish&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SecurityService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SecurityClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;());&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SecurityClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WhenToldTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SendRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsAny&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;Because&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Authenticate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;It&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should_request_a_token&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SecurityClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WasTaldTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RequestToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SecurityService&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
                
                            <pubDate>Fri, 05 Aug 2016 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2016/08/05/announcing-mspec-for-net-core?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2016/08/05/announcing-mspec-for-net-core?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>How does TypeScript discover type declarations and definitions for JavaScript code?</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;In this blog post I will cover how TypeScript discovers type declarations and the subtle differences in what they should look like depending on where they live.&lt;/p&gt;

&lt;p&gt;Edit: Note that Visual Studio IDE, Visual Studio Code and possibly other editors have built their TypeScript/JavaScript intellisense on top of the TypeScript language service (that is - TypeScript itself), so all of the below apply for those as well.&lt;/p&gt;

&lt;p&gt;Let’s say that we have a JavaScript module like the one below and we want to consume it together with type declarations either in TypeScript or JavaScript (TypeScripts can process JavaScript and provide intellisense via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowJs&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;our-javascript-module-code&quot;&gt;Our JavaScript module code&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;hello.js&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sayHi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;```Hi &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;!```&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We want to consume it in TypeScript and we do this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;main.ts&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Ivan&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Zlatev&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will trigger a search for type declarations during the compilation/transpilation phase, so let’s go through the various possibilities.&lt;/p&gt;

&lt;h2 id=&quot;tripple-slash-comments&quot;&gt;Tripple slash comments&lt;/h2&gt;

&lt;p&gt;The legacy way to tell TypeScript that we have type declarations we want it to use for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello&lt;/code&gt; is to use a triple slash comment like this:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;/// &amp;lt;reference path=&quot;path/to/declarations.d.ts&quot; /&amp;gt;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Ivan&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Zlatev&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;declarations.d.ts&lt;/code&gt; that looks like this:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;declare module &apos;hello&apos;&lt;/code&gt;. This is an &lt;em&gt;ambient declaration&lt;/em&gt; and what it means is that we are telling TypeScript: “There exists a module called “hello” which exposes these types”.&lt;/p&gt;

&lt;p&gt;This is not particlarly great approach and is error and frustration prone - We have to manually maintain the list of references and ensure the ordering is correct.&lt;/p&gt;

&lt;p&gt;One benefit of this method is that it allows the creation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import-all.d.ts&lt;/code&gt; type of file with a list of references - a method used by &lt;a href=&quot;https://github.com/typings/typings&quot;&gt;typings&lt;/a&gt; (the successor to &lt;a href=&quot;definitelytyped.org&quot;&gt;tsd&lt;/a&gt;) to create an “index” file with reference list to all installed typings.&lt;/p&gt;

&lt;h2 id=&quot;tsconfigjson&quot;&gt;tsconfig.json&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsconfig.json&lt;/code&gt; file defines the TypeScript project/workspace when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsc --project directory_here&lt;/code&gt; is used. Among other things it supports two modes for defining the code files to process in the workspace/project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(default) Include all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.ts&lt;/code&gt; (so also &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.d.ts&lt;/code&gt;) files recursively. Files/paths can optionally be excluded using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exclude: [ &quot;path1&quot;, &quot;path2&quot; ]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Explicitly include a specific set of files for processing using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include: [ &quot;path1&quot;, &quot;path2&quot; ]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What this means for us is that as long as the our type declarations files are included (implicitly or explicitly) in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsconfig.json&lt;/code&gt; &lt;strong&gt;we don’t need to use triple slash comments&lt;/strong&gt; to reference them, because they will already be part of the project/workspace.&lt;/p&gt;

&lt;p&gt;A typical &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsconfig.json&lt;/code&gt; can look like this.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;es5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;noImplicitAny&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;commonjs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;moduleResolution&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;outDir&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;compileOnSave&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exclude&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;node_modules&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.vscode&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You will find that when using &lt;a href=&quot;https://github.com/typings/typings&quot;&gt;typings&lt;/a&gt; (the successor to &lt;a href=&quot;definitelytyped.org&quot;&gt;tsd&lt;/a&gt;) it will automatically ensure that the type declarations are included in the paths of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;local-javascript-module-type-declaration&quot;&gt;Local JavaScript module type declaration&lt;/h2&gt;

&lt;p&gt;Given a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello.js&lt;/code&gt; file which exports a module TypeScript will look for  A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello.d.ts&lt;/code&gt; file (same file name basically).&lt;/p&gt;

&lt;p&gt;In our case the type declaration in that file will look like the one below. Note how there is no longer a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;declare module &apos;hello&apos;&lt;/code&gt; bit in the file. We no how an external module type declaration (and not an ambient one) :&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;npm-package-typings&quot;&gt;NPM package “typings:”&lt;/h2&gt;

&lt;p&gt;Given a module named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello&lt;/code&gt; TypeScript will look across the NPM packages and inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package.json&lt;/code&gt; for any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typings: &apos;path/to/definitions.ts.d&apos;&lt;/code&gt; and use that. In our case again will look like this:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;note-the-meaning-of-ambient&quot;&gt;Note the meaning of “ambient”&lt;/h2&gt;

&lt;p&gt;In a web browser environment when jQuery is imported - it declares a global variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt;, which is accessible everywhere. Antother example is the Node environment - we get access to a bunch of functions things without having to import specific packages.&lt;/p&gt;

&lt;p&gt;In such a case we are likely to see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.d.ts&lt;/code&gt; with global ambient declarations (“something has declared X function/variable and it looks like this”). E.g. for jQuery something like &lt;a href=&quot;https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/jquery/jquery.d.ts#L3221&quot;&gt;this&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JQueryStatic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately some of the terminology/naming is inconsistent across tsd, typings and TypeScript itself (&lt;a href=&quot;https://github.com/typings/core/issues/12&quot;&gt;GitHub issue&lt;/a&gt;), which I personally found frustrating when trying to write type declarations for the first time.&lt;/p&gt;

</description>
                
                            <pubDate>Tue, 07 Jun 2016 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2016/06/07/how-does-typescript-discover-type-declarations-definitions-javascript?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2016/06/07/how-does-typescript-discover-type-declarations-definitions-javascript?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Farewell project.json - hello MSBuild and .csproj (.NET Core)</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;h2 id=&quot;farewell-projectjson&quot;&gt;Farewell project.json&lt;/h2&gt;

&lt;p&gt;There was a fairly important update from Microsoft last week, which I personally felt went a bit under the cover.&lt;/p&gt;

&lt;p&gt;The .NET Core (and other teams) have decided to &lt;strong&gt;drop &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; and go back to MSBuild and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.csproj&lt;/code&gt;&lt;/strong&gt;. This is not something that’s already happened in the just released .Net Core RC2 and ASP.NET Core RC2, but it’s happening.&lt;/p&gt;

&lt;p&gt;Wondering where that announcement was made? As far as I know - there wasn’t necessarily one. It was mentioned in the stand-up (see the video at the end of this post).&lt;/p&gt;

&lt;p&gt;This is fairly disappointing, because the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; was a breath of fresh air. However it’s understandable (to an extend):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It would make the transition of existing Visual Studio solutions to .NET Core straightforward&lt;/li&gt;
  &lt;li&gt;It’s a huge change. It will enable leveraging existing investment in CI/RM based around MSBuild.&lt;/li&gt;
  &lt;li&gt;There is &lt;em&gt;a lot&lt;/em&gt; going on under the hood during build in MSBuild. Think incremental compilation, resolving build-time dependencies, configuration management and tons more (hidden behind the e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Microsoft.CSharp.targets&lt;/code&gt; imported by every project). And all of that will have to be re-implemented.&lt;/li&gt;
  &lt;li&gt;Too much work to ship &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet cli&lt;/code&gt; on time - remember that it’s no longer just about ASP.NET Core, but also console apps, UWP apps, Xamarin apps.&lt;/li&gt;
  &lt;li&gt;The .NET core team would have eventually ended up probably implementing/re-implementing parts of MSBuild.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still that doesn’t make me happier right now.&lt;/p&gt;

&lt;h2 id=&quot;hello-msbuild-and-csproj&quot;&gt;Hello MSBuild and .csproj&lt;/h2&gt;

&lt;p&gt;Appears this is what will happen in future releases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.xproj&lt;/code&gt; will be replaced by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.csproj&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Features in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; will start getting merged back into the the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.csproj&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;It is not yet clear what they are going to do about the packages list, but it was mentioned they might keep it as json under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nuget.json&lt;/code&gt; or merge it into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csproj&lt;/code&gt;. GitHub issue tracking this here: &lt;a href=&quot;https://github.com/aspnet/Home/issues/1433&quot;&gt;https://github.com/aspnet/Home/issues/1433&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Supposedly that transition should be smooth and potentially automatic if using Visual Studio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The good news is that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MSBuild is open source and &lt;a href=&quot;https://github.com/Microsoft/msbuild&quot;&gt;available on GitHub&lt;/a&gt; and is bound to become fully cross-platform&lt;/li&gt;
  &lt;li&gt;They is an effort to dramatically simplify and trim the structure of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csproj&lt;/code&gt; - e.g. remove the requirement to have a list of files. GitHub issue here: &lt;a href=&quot;https://github.com/dotnet/roslyn-project-system/issues/40&quot;&gt;https://github.com/dotnet/roslyn-project-system/issues/40&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;There is a new revamped project system coming which will enable a lot of scenarios without the need for Visual Studio: &lt;a href=&quot;https://github.com/dotnet/roslyn-project-system/&quot;&gt;https://github.com/dotnet/roslyn-project-system/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The goal is that even with the MSBuild set-up working with builds and project will be as seamless in Visual Studio IDE as outside of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;announcement-video&quot;&gt;Announcement video&lt;/h2&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/P9HqMZviaMg?start=1713&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
</description>
                
                            <pubDate>Tue, 17 May 2016 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2016/05/17/farewell-project-json-hello-msbuild-and-csproj?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2016/05/17/farewell-project-json-hello-msbuild-and-csproj?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Machine.Specifications.Runner.VisualStudio 2.0.0-rc1 is out with many improvements</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;This is a significant update to the Test Adapter with substantial improvements on which I have been working over the past weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get it here:&lt;/strong&gt; &lt;a href=&quot;https://github.com/machine-visualstudio/machine.vstestadapter/releases/tag/v2.0.0-rc1&quot;&gt;https://github.com/machine-visualstudio/machine.vstestadapter/releases/tag/v2.0.0-rc1&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;New test discovery engine built directly on top of MSpec replaces old Mono.Cecil based one:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Full support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[Behavior]&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Behaves_like&amp;lt;&amp;gt;&lt;/code&gt; and everything MSpec&lt;/li&gt;
      &lt;li&gt;Full support for assembly binding (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.config&lt;/code&gt;) during test discovery (and execution)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Out of the box support for Visual Studio Online, TFS, Visual Studio Team Services through the NuGet package&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Major performance improvements when running whole test assemblies&lt;/li&gt;
      &lt;li&gt;Much clearer test result output&lt;/li&gt;
      &lt;li&gt;Fully compatible with VS parallel assembly execution (enabled through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MaxCpuCount&lt;/code&gt;  set to 0 in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.runsettings&lt;/code&gt;)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Inner exceptions are now displayed in failed test results&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Tests in Visual Studio IDE are now displayed as English text&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/79742/13714426/5b1428be-e7c6-11e5-9afd-60486c5c3482.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/79742/13713366/88985202-e7c0-11e5-9019-5295190ba649.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/79742/13713375/923e9f32-e7c0-11e5-8689-045ca9949486.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Fri, 11 Mar 2016 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2016/03/11/machine-specifications-runner-visualstudio-2-0-0-rc1?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2016/03/11/machine-specifications-runner-visualstudio-2-0-0-rc1?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>MSpec (Machine.Specifications) Visual Studio Adapter 1.7.0 released</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;In the last 2 weeks or so, I have given a helping hand to Jonathan Wilkins with the MSpec Visual Studio adapter project. My initial main focus was to get the adapter nuget ready, so that it can be used in Visual Studio Online (now Team Services) seamlessly. I have also set-up &lt;a href=&quot;https://ci.appveyor.com/project/machine-visualstudio/machine-vstestadapter&quot;&gt;a CI environment in AppVeyor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If the udpated Visual Studio extensions is not live yet at the time you read this blog post - you can grab it from the &lt;strong&gt;GitHub release: https://github.com/machine-visualstudio/machine.vstestadapter/releases/tag/v1.7.0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Release notes below. If you are curious what is potentially cooking in the next 1.8.0 relase - you can look here: https://github.com/machine-visualstudio/machine.vstestadapter/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.8.0&lt;/p&gt;

&lt;h2 id=&quot;whats-new&quot;&gt;What’s new&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Upgraded to use Machine.Specifications 0.9.3&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;The adapter now is distributed through a NuGet package in addition to the Visual Studio extension to enable Continuous Integration/Delivery scenario
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.nuget.org/packages/Machine.Specifications.Runner.VisualStudio/&quot;&gt;https://www.nuget.org/packages/Machine.Specifications.Runner.VisualStudio/&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The adaptor is now set-up with Continuous Integration and builds of the NuGet package and VSIX extension can be downloaded from AppVeyor
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://ci.appveyor.com/project/machine-visualstudio/machine-vstestadapter&quot;&gt;https://ci.appveyor.com/project/machine-visualstudio/machine-vstestadapter&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;related-documentation&quot;&gt;Related Documentation&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/machine-visualstudio/machine.vstestadapter/wiki/Visual-Studio-Team-Services-(Visual-Studio-Online-VSO)-Support&quot;&gt;Using the adaptor in Visual Studio Team Services (Visual Studio Online) build and release&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/79742/12643294/311c1d94-c5b3-11e5-90a9-741ca940ca36.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
</description>
                
                            <pubDate>Thu, 28 Jan 2016 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2016/01/28/mspec-visualstudio-adapter-1-7-0-released?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2016/01/28/mspec-visualstudio-adapter-1-7-0-released?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>CorrelatorSharp: Your one stop shop for context-aware logging and diagnostics</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;In the world of microservices and distributed systems it is very important to relate logging and diagnostic information of multiple services in the context of an operation to quickly diagnose issues.&lt;/p&gt;

&lt;h2 id=&quot;what-is-correlatorsharp&quot;&gt;What is CorrelatorSharp?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ivanz/CorrelatorSharp&quot;&gt;CorrelatorSharp&lt;/a&gt; is a .NET library that enables context-aware logging and correlation with no code changes or minimal such.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ivanz/CorrelatorSharp&quot;&gt;CorrelatorSharp&lt;/a&gt; is &lt;strong&gt;async/await aware&lt;/strong&gt; and the current activity &lt;strong&gt;flows across tasks and threads automatically&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ivanz/CorrelatorSharp&quot;&gt;CorrelatorSharp&lt;/a&gt; supports out of the box (at the time of writing this post):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ASP.NET MVC 5&lt;/li&gt;
  &lt;li&gt;ASP.NET Web API&lt;/li&gt;
  &lt;li&gt;RestSharp&lt;/li&gt;
  &lt;li&gt;NLog&lt;/li&gt;
  &lt;li&gt;Application Insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Support for the following is also planned: WCF server/client, Azure Service Bus, Azure Storage Queue, CoreCLR.&lt;/p&gt;

&lt;h2 id=&quot;using-correlatorsharp-in-5-minutes&quot;&gt;Using CorrelatorSharp in 5 minutes&lt;/h2&gt;

&lt;h3 id=&quot;1-enable-in-web-api-in-service-b&quot;&gt;1. Enable in Web API in Service “B”&lt;/h3&gt;

&lt;p&gt;Use the CorrelatorSharp.WebApi package:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CorrelationIdActionFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-log-the-current-correlation-id&quot;&gt;2. Log the current correlation id&lt;/h3&gt;

&lt;p&gt;You can do it manually (or through one of the CorrelatorSharp packages such as &lt;em&gt;CorrelatorSharp.NLog&lt;/em&gt; or &lt;em&gt;CorrelatorSharp.ApplicationInsights&lt;/em&gt;):&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity Id: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity Name: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity ParentId: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-pass-the-correlation-id-from-service-a-to-service-b&quot;&gt;3. Pass the correlation id from Service “A” to Service “B”&lt;/h3&gt;

&lt;p&gt;If you are using RestSharp you can use the &lt;em&gt;CorrelatorSharp.RestSharp&lt;/em&gt;  or just add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Correlation-Id&lt;/code&gt; header to your requests:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;RestRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddCorrelationHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-manage-activity-scopes&quot;&gt;4. Manage activity scopes&lt;/h3&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Operation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity Id: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity Name: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity ParentId: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nestedScope&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Nested Operation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity Id: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity Name: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Current Activity ParentId: &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActivityScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Example output:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4050&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a075&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;51d&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;17720&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a73045e&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Operation&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2d7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aa66d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;62&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;406d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;91&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea3305690675&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Nested&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Operation&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4050&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a075&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;51d&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;17720&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a73045e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;get-it-now&quot;&gt;Get it now&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.nuget.org/packages?q=correlatorsharp&quot;&gt;NuGet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ivanz/CorrelatorSharp&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
                
                            <pubDate>Sat, 12 Dec 2015 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2015/12/12/CorrelatorSharp?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2015/12/12/CorrelatorSharp?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>MarketInvoice Roslyn Pack 0.1 released</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;h1 id=&quot;innovation-mondays-at-marketinvoice&quot;&gt;Innovation Mondays at MarketInvoice&lt;/h1&gt;

&lt;p&gt;At &lt;a href=&quot;http://tech.marketinvoice.com&quot;&gt;MarketInvoice&lt;/a&gt; we run “Innovation Mondays” on the first Monday of every Sprint (at the time of writing this post we are running two week sprints). It’s an opportunity for the Engineering team to hack on new ideas and projects, explore new technologies and learn new things either in groups or individually. We discuss our achievements, prototypes and findings in our weekly two hour Wednesday lunch. We use this lunch to also have lunch and learn sessions (we recently had an F# and Akka.Net one), have an open discussion about our technology stack, processes, activities and anything that gets raised by team members prior to the team meeting.&lt;/p&gt;

&lt;p&gt;One of the mini-projects from this week is the first release of our MarketInvoice Roslyn Pack, which is to become a collection of refactorings, code formatters, code analysis and code fixes.&lt;/p&gt;

&lt;h1 id=&quot;download-and-install&quot;&gt;Download and Install&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Download Visual Studio Extension&lt;/strong&gt;: &lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/9a7f4b28-f068-4417-a021-8a770d352ea9&quot;&gt;https://visualstudiogallery.msdn.microsoft.com/9a7f4b28-f068-4417-a021-8a770d352ea9&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code here&lt;/strong&gt;: &lt;a href=&quot;https://github.com/marketinvoice/MarketInvoice.CodeAnalysis&quot;&gt;https://github.com/marketinvoice/MarketInvoice.CodeAnalysis&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;whats-included&quot;&gt;What’s included&lt;/h1&gt;

&lt;p&gt;We’ve decided to stay minimal and have implemented two refactorings only:&lt;/p&gt;

&lt;h2 id=&quot;1-break-parameters-and-arguments-apart&quot;&gt;1. Break parameters and arguments apart&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-12-marketinvoice-roslyn-pack-released/break-parameters-apart.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/content/2015-10-12-marketinvoice-roslyn-pack-released/break-arguments-apart.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;2-line-up-parameters-and-arguments&quot;&gt;2. Line-up parameters and arguments&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-12-marketinvoice-roslyn-pack-released/line-up-parameters.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/content/2015-10-12-marketinvoice-roslyn-pack-released/line-up-arguments.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;what-about-refactoring-essentials&quot;&gt;What about Refactoring Essentials?&lt;/h1&gt;

&lt;p&gt;We are aware (and are using) the &lt;a href=&quot;http://vsrefactoringessentials.com/&quot;&gt;Refactoring Essentials&lt;/a&gt;, but we have decided that at least initially we would like to iterate rapidly and thus not be tied in to their release cycle. Having said that - we will definitely look into contributing some of our work to Refactoring Essentials.&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 12 Oct 2015 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2015/10/12/marketinvoice-roslyn-pack-released?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2015/10/12/marketinvoice-roslyn-pack-released?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>FluentMigrator Part 2/3: Continuous Integration and Testing with database migrations</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;h1 id=&quot;in-this-series&quot;&gt;In this series&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/09/12/fluentmigrator-part-1/&quot;&gt;FluentMigrator Part 1/3: Creating and running our first database migration&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;FluentMigrator Part 2/3: Continuous Integration and Testing with database migrations (this post)&lt;/li&gt;
  &lt;li&gt;FluentMigrator Part 3/3: Continuous Delivery with database migrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having created and ran our first database migration - in this post we are going to cover the following scenario:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We want to write integration tests that hit a real database in our local developer environment&lt;/li&gt;
  &lt;li&gt;We want to also run those tests on our build server as part of every check-in&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;the-plan&quot;&gt;The Plan&lt;/h1&gt;

&lt;p&gt;We want to be able to do the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create a temporary unique database for use with our test fixture only&lt;/li&gt;
  &lt;li&gt;Migrate the database to the latest version to match the code&lt;/li&gt;
  &lt;li&gt;Run the tests&lt;/li&gt;
  &lt;li&gt;Delete the temporary database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The end goal is to be able to write tests like this using a nicely reusable base test fixture that will do all the magic for us.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SavingCarsNUnitTest&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DatabaseTestFixtureBase&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;When_a_car_is_saved_in_the_database_it_should_succeed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CarsDbContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CarsDbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Make&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;make&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SaveChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestFixture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DatabaseTestFixtureBase&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IntegrationTestLifecycle&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_testLifeCycle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IntegrationTestLifecycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConnectionString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_testLifeCycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestFixtureSetUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetUpFixture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_testLifeCycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConnectionStringTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestFixtureTearDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TearDownFixture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_testLifeCycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TearDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_testLifeCycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;automating-the-creation-and-deletaion-of-the-database-for-the-test-fixture&quot;&gt;Automating the creation and deletaion of the database for the test fixture&lt;/h1&gt;

&lt;p&gt;The first problem that we face is that we need a database to run our tests against. However:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We need a &lt;em&gt;temporary&lt;/em&gt; database to avoid sharing it across test runs and thus inconsistent states and false positives&lt;/li&gt;
  &lt;li&gt;Whichever way we automate the database creation process - we need to tell our tests where to connect to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The way we’ve solved this problem at &lt;a href=&quot;https://marketinvoice.com&quot;&gt;MarketInvoice&lt;/a&gt; is by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Running a SQL Server instance (free through MSDN) to be used by our integration tests&lt;/li&gt;
  &lt;li&gt;We’ve built an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IntegrationTestLifecycle&lt;/code&gt; component that:
    &lt;ul&gt;
      &lt;li&gt;Creates a temporary database with a unique name&lt;/li&gt;
      &lt;li&gt;Provides a connection string to the consumer&lt;/li&gt;
      &lt;li&gt;Cleans up and deletes the temporary database on request&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s dive in the code of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IntegrationTestLifecycle&lt;/code&gt; class a bit…&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IntegrationTestLifecycle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// &amp;lt;..snip...&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConnectionString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionStringTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uniqueDatabaseConnectionString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GenerateUniqueDatabaseName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connectionStringTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nf&quot;&gt;CreateDatabase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniqueDatabaseConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;DatabaseMigrationRunner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MigrateDatabase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SqlServer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uniqueDatabaseConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;



        &lt;span class=&quot;n&quot;&gt;ConnectionString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uniqueDatabaseConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// &amp;lt;..snip...&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s pretty straightforward what’s happening here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We are generating a unique database name to use:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GenerateUniqueDatabaseName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;originialConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SqlConnectionStringBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionInfo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SqlConnectionStringBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;originialConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;connectionInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InitialCatalog&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CultureInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InvariantCulture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                                    &lt;span class=&quot;s&quot;&gt;&quot;{0}_{1}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                                    &lt;span class=&quot;n&quot;&gt;connectionInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InitialCatalog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                                    &lt;span class=&quot;n&quot;&gt;Guid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;NewGuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;We are creating a new database on the database server using that name:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateDatabase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SqlConnectionStringBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionInfo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SqlConnectionStringBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;SqlConnectionStringBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;master&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SqlConnectionStringBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;InitialCatalog&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SqlConnection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sqlConnection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SqlConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;master&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SqlCommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;createDbCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sqlConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sqlConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;createDbCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CommandTimeout&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DEFAULT_SQL_COMMAND_TIMEOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;createDbCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CommandText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;@&quot;CREATE DATABASE [{0}] 
ALTER DATABASE [{0}] SET ALLOW_SNAPSHOT_ISOLATION ON 
ALTER DATABASE [{0}] SET RECOVERY SIMPLE&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InitialCatalog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;createDbCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ExecuteNonQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sqlConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;We are migrating the database to the latest version (covered a bit later in this post)&lt;/li&gt;
  &lt;li&gt;We are exposing the brand new connection string to the consumer of the component.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;migrating-the-newly-created-database&quot;&gt;Migrating the newly created database&lt;/h1&gt;

&lt;p&gt;In my previous blog post we looked at how to write a new migration on top of an existing schema. In the case of our integration tests’ life-cycle we are creating a new database, so we need to import the schema. We can do that by creating a version &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; migration.&lt;/p&gt;

&lt;p&gt;To do that we are going to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Export the current schema using SQL Server Management Studio using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Generate Scripts&lt;/code&gt; functionality&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-09-13-fluentmigrator-part2/export-schema.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Remove any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GO&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;USE&lt;/code&gt; statements and tell it not to generate the “CREATE DATABASE” statement. It will end up looking like this:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ANSI_NULLS&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QUOTED_IDENTIFIER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IDENTITY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nvarchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CLUSTERED&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ASC&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;WITH&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PAD_INDEX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;OFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STATISTICS_NORECOMPUTE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;OFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IGNORE_DUP_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;OFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ALLOW_ROW_LOCKS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ALLOW_PAGE_LOCKS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TEXTIMAGE_ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;Add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.sql&lt;/code&gt; file as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0_CreateSchema.sql&lt;/code&gt; in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DatabaseMigrations&lt;/code&gt; project and set it to be an &lt;strong&gt;Embedded Resource&lt;/strong&gt; (note how the file name will match our migration name):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-09-13-fluentmigrator-part2/migration.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Write our migration:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;_0_CreateSchema&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ForwardOnlyMigration&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Up&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;EmbeddedScript&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0_CreateSchema.sql&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;Finally let’s expose a simple Migration runner from our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DatabaseMigrations&lt;/code&gt; project using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluentMigrator.Runners&lt;/code&gt; NuGet package:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DatabaseMigrationRunner&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MigrateDatabase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;databaseType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;migrationsAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;RunnerContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;runnerContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RunnerContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TextWriterAnnouncer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Database&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;databaseType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Targets&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;migrationsAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TaskExecutor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runnerContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-09-13-fluentmigrator-part2/tests.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;downloading-and-running-the-sample-code&quot;&gt;Downloading and running the sample code&lt;/h1&gt;

&lt;p&gt;You can find all code in this article at: &lt;a href=&quot;https://github.com/ivanz/FluentMigratorSample&quot;&gt;https://github.com/ivanz/FluentMigratorSample&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To edit the SQL Server used by the tests edit the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Settings.settings&lt;/code&gt; file.&lt;/p&gt;

&lt;h1 id=&quot;speeding-up-test-runs&quot;&gt;Speeding up test runs&lt;/h1&gt;

&lt;p&gt;The way we speed up test runs is by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Running tests in multiple assemblies at the same time (For MSpec we use our &lt;a href=&quot;https://github.com/ivanz/Machine.Specifications.TeamCityParallelRunner&quot;&gt;parallel runner for TeamCity&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Sharing a database instance between a group of common tests.&lt;/li&gt;
&lt;/ul&gt;

</description>
                
                            <pubDate>Sun, 13 Sep 2015 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2015/09/13/fluentmigrator-part-2?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2015/09/13/fluentmigrator-part-2?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>FluentMigrator Part 1/3: Creating and running our first database migration</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;h1 id=&quot;in-this-series&quot;&gt;In this series&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;FluentMigrator Part 1/3: Creating and running our first database migration (this post)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/09/13/fluentmigrator-part-2/&quot;&gt;FluentMigrator Part 2/3: Continuous Integration and Testing with database migrations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;FluentMigrator Part 3/3: Continuous Delivery with database migrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post we are going to cover:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;What FluentMigrator is&lt;/li&gt;
  &lt;li&gt;How to create a database migration&lt;/li&gt;
  &lt;li&gt;How to run our database migration and then roll it back&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;what-is-fluentmigrator&quot;&gt;What is FluentMigrator&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/schambers/fluentmigrator/&quot;&gt;FluentMigrator&lt;/a&gt; is a migration framework for .NET much like Ruby on Rails Migrations. Migrations are a structured way to alter your database schema and are an alternative to creating lots of sql scripts that have to be run manually by every developer involved. Migrations solve the problem of evolving a database schema for multiple databases (for example, the developer’s local database, the test database and the production database). Database schema changes are described in classes written in C# that can be checked into a version control system. [&lt;a href=&quot;https://github.com/schambers/fluentmigrator/blob/master/README.textile&quot;&gt;source&lt;/a&gt;]&lt;/p&gt;

&lt;h1 id=&quot;before-we-start&quot;&gt;Before we start&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;You can download all the code from this post at: &lt;a href=&quot;https://github.com/ivanz/FluentMigratorSample&quot;&gt;https://github.com/ivanz/FluentMigratorSample&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;You will need either a SQL Server Express, SQL Server or an Azure SQL Database if you want to run the example.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;our-visual-studio-solution&quot;&gt;Our Visual Studio solution&lt;/h2&gt;

&lt;p&gt;Let’s say we are building a Web App to catalogue cars. Our solution contains:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Domain&lt;/code&gt; - class library for our model and data access&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WebApp&lt;/code&gt;- Simple MVC app&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DatabaseMigrations&lt;/code&gt; - class library for our database migrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what it looks like in Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-09-12-fluentmigrator-part1/solution.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And this is what it looks like when we run it:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-09-12-fluentmigrator-part1/webapp.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Any Entity Framework automatic database initialization/migration has been disabled in the data context.&lt;/p&gt;

&lt;h2 id=&quot;domain-model-and-initial-database-schema&quot;&gt;Domain model and initial database schema&lt;/h2&gt;

&lt;p&gt;Our domain model:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Car&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And our initial schema that matches that. Let’s assume for now that this schema is already in place in the database. We will revisit that later.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;USE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;master&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DATABASE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CarsDb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;USE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CarsDb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;INT&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IDENTITY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NVARCHAR&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CLUSTERED&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ASC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;creating-our-first-database-migration&quot;&gt;Creating our first database migration&lt;/h1&gt;

&lt;p&gt;Let’s add a new property to the our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Car&lt;/code&gt; - let’s say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Make&lt;/code&gt;, so now it looks like this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Car&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// new:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Make&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To create our first database migration we need to add the &lt;a href=&quot;https://www.nuget.org/packages/FluentMigrator&quot;&gt;FluentMigrator NuGet package&lt;/a&gt; to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DatabaseMigrations&lt;/code&gt; project.&lt;/p&gt;

&lt;p&gt;Then we can use the fluent syntax to change the database schema to include the new column:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;201509121634_Add_Make_Column_To_Car.cs&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;201509121634&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Add_Make_Column_To_Car&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Migration&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Up&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Make&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;OnTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Cars&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AsString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaxValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Down&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Make&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FromTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Cars&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;anatomy-of-a-database-migration&quot;&gt;Anatomy of a database migration&lt;/h2&gt;

&lt;p&gt;Every migration has a version and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MigrationAttribute&lt;/code&gt; enables us to define the version of the database migration.&lt;/p&gt;

&lt;p&gt;Using a timestamps-based version number (when the migration file was created) in the format of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;YearMonthDateHourMinute&lt;/code&gt; works really well for both the file name and the migration version, because:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Files in Visual Studio are displayed in the order they were created&lt;/li&gt;
  &lt;li&gt;Version number clashes are extremely unlikely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Up&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Down&lt;/code&gt; methods (unless it’s a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForwardOnlyMigration&lt;/code&gt;) - to upgrade and downgrade the schema.&lt;/p&gt;

&lt;p&gt;The fluent syntax of FluentMigrator supports pretty much everything you can think off:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Creating, altering columns, tables, foreign keys, indices, etc. .&lt;/li&gt;
  &lt;li&gt;Executing SQL statements through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Execute.Sql(&quot;statements&quot;)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Executing embedded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.sql&lt;/code&gt; files through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Execute.Script(&quot;filename&quot;)&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Execute.EmbeddedScript(&quot;filename&quot;)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;running-our-first-migration-and-rolling-it-back&quot;&gt;Running our first migration and rolling it back&lt;/h1&gt;

&lt;p&gt;There are many ways to run the database migration we just created:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Command Line&lt;/li&gt;
  &lt;li&gt;PowerShell script&lt;/li&gt;
  &lt;li&gt;MSbuild task&lt;/li&gt;
  &lt;li&gt;NAnt task&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s use the command line tool provided by the &lt;a href=&quot;https://www.nuget.org/packages/FluentMigrator.Tools&quot;&gt;FluentMigrator.Tools NuGet package&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once installed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Migrator.exe&lt;/code&gt; can be found at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packages\FluentMigrator.Tools.1.6.0\tools\AnyCPU\40&lt;/code&gt; and to migrate our database to the latest version we just have to point it to our database and supply the assembly that contains the database migrations.&lt;/p&gt;

&lt;div class=&quot;language-batch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s2&quot;&gt;&quot;packages\FluentMigrator.Tools.1.6.0\tools\AnyCPU\40\Migrate.exe&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;-a &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;DatabaseMigrations&lt;/span&gt;\bin\Debug\DatabaseMigrations.dll&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;-provider &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;SqlServer&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;-connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Server=.;Database=CarsDb;Integrated Security=True;&quot;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;===============================&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;FluentMigrator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;================================&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;Source&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Code&lt;/span&gt;:
  &lt;span class=&quot;kd&quot;&gt;http&lt;/span&gt;://github.com/schambers/fluentmigrator
&lt;span class=&quot;kd&quot;&gt;Ask&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;For&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Help&lt;/span&gt;:
  &lt;span class=&quot;kd&quot;&gt;http&lt;/span&gt;://groups.google.com/group/fluentmigrator&lt;span class=&quot;na&quot;&gt;-google-group
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Using&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Database&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;SqlServer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;.&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;Database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;CarsDb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;Integrated&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;m&quot;&gt;201509121634&lt;/span&gt;: &lt;span class=&quot;kd&quot;&gt;Add_Make_Column_To_Car&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;migrating&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Beginning&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Transaction&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;CreateColumn&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Cars&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Make&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Committing&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Transaction&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;201509121634&lt;/span&gt;: &lt;span class=&quot;kd&quot;&gt;Add_Make_Column_To_Car&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;migrated&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;completed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the background this will create a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VersionInfo&lt;/code&gt; table that Fluent Migrator will use to track which version the database schema is at:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-09-12-fluentmigrator-part1/versioninfo-table.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And to rollback one version:&lt;/p&gt;

&lt;div class=&quot;language-batch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s2&quot;&gt;&quot;packages\FluentMigrator.Tools.1.6.0\tools\AnyCPU\40\Migrate.exe&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;--task &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;rollback&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;--steps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;-a &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;DatabaseMigrations&lt;/span&gt;\bin\Debug\DatabaseMigrations.dll&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;-provider &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;SqlServer&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;^
&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;-connection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Server=.;Database=CarsDb;Integrated Security=True;&quot;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;===============================&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;FluentMigrator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;================================&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;Source&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Code&lt;/span&gt;:
  &lt;span class=&quot;kd&quot;&gt;http&lt;/span&gt;://github.com/schambers/fluentmigrator
&lt;span class=&quot;kd&quot;&gt;Ask&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;For&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Help&lt;/span&gt;:
  &lt;span class=&quot;kd&quot;&gt;http&lt;/span&gt;://groups.google.com/group/fluentmigrator&lt;span class=&quot;na&quot;&gt;-google-group
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Using&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Database&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;SqlServer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;.&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;Database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;CarsDb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;Integrated&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;m&quot;&gt;201509121634&lt;/span&gt;: &lt;span class=&quot;kd&quot;&gt;Add_Make_Column_To_Car&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;reverting&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Beginning&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Transaction&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;DeleteColumn&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Cars&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Make&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Committing&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Transaction&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;201509121634&lt;/span&gt;: &lt;span class=&quot;kd&quot;&gt;Add_Make_Column_To_Car&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;reverted&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[+]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;completed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;

&lt;p&gt;That’s pretty much the high level overview and in the next post we are going to look at how do we utilize FluentMigrator in a Continuous Integration scenario.&lt;/p&gt;

</description>
                
                            <pubDate>Sat, 12 Sep 2015 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2015/09/12/fluentmigrator-part-1?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2015/09/12/fluentmigrator-part-1?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Using, configuring and distributing Roslyn analysers in teams</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;h1 id=&quot;what-are-the-roslyn-analysers&quot;&gt;What are the Roslyn analysers?&lt;/h1&gt;

&lt;p&gt;As you should already know Roslyn is the name of new C# 6.0 (and Visual Basic) compiler, written entirely in C# (and VB for the VB one). The old compiler was written in C++ and this is a complete re-implementation. You can find Roslyn’s source code &lt;a href=&quot;https://github.com/dotnet/roslyn&quot;&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However Roslyn is not just a compiler. It’s also and SDK (“.Net Compiler Platform”) which exposes the compiler as a service. Tools (such as Visual Studio, ReSharper, CodeRush, LinqPad) can directly hook into the syntax tree information exposed by the compiler to achieve various jobs such as code auto-completion, refactoring and code analysis. Previously those tools had to implement their own C# code parsing, effectively duplicating the compiler’s job. It’s a non-trivial task, so that’s why libraries such as &lt;a href=&quot;https://github.com/icsharpcode/SharpDevelop/wiki/NRefactory&quot;&gt;NRefactory&lt;/a&gt; became popular. You will find it used across various tools - e.g. LinqPad, Xamarin Studio (I think).&lt;/p&gt;

&lt;p&gt;In simplified terms Roslyn analysers are plug-ins that plug into the Roslyn compilation (parsing) pipeline and are able to spit out warnings and errors whilst editing code in Visual Studio and during compilation. They can also provide “code fixes”/refactorings.&lt;/p&gt;

&lt;p&gt;I am not going to drill into the details of how the analysers are implemented or how to implemented one in this post, but focus more on how to use them across a team and continuous integration.&lt;/p&gt;

&lt;p&gt;You can get all source code from this post at: &lt;a href=&quot;https://github.com/ivanz/RoslynAnalysersUsageSample&quot;&gt;https://github.com/ivanz/RoslynAnalysersUsageSample&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;using-roslyn-analysers-as-visual-studio-extensions&quot;&gt;Using Roslyn analysers as Visual Studio Extensions&lt;/h1&gt;

&lt;p&gt;The easiest way to get some extra analysers is to install the really good &lt;a href=&quot;http://vsrefactoringessentials.com/&quot;&gt;VS Refactoring Essentials&lt;/a&gt; analysers pack, which contains around &lt;a href=&quot;http://vsrefactoringessentials.com/Features/All#collapseCSharpAnalyzers&quot;&gt;100 of them&lt;/a&gt; (and lots of refactoring tools).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/extensions.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you have them installed you will start seeing some warnings, such as this one:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/what-it-looks-like.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; You may see sporadic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MissingAnalyzerReference&lt;/code&gt; warnings with Refactoring Essentials and StyleCop to do with Visual Basic, which you can safely ignore. This bug is tracked &lt;a href=&quot;https://github.com/icsharpcode/RefactoringEssentials/issues/98&quot;&gt;in this GitHub issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is great, however it’s not really useful unless everyone in the team has the extension installed, which on its own can be difficult to enforce or manage consistently.&lt;/p&gt;

&lt;h1 id=&quot;note-on-solution-error-visualizer&quot;&gt;Note on Solution Error Visualizer&lt;/h1&gt;

&lt;p&gt;I am using the Solution Error Visualizer plug-in as part of the free
&lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/34ebc6a2-2777-421d-8914-e29c1dfa7f5d&quot;&gt;Productivity Power Tools for Visual Studio 2015 extension&lt;/a&gt; by Microsoft.  This is where the underlining in the Solution Explorer of errors and warnings comes from.&lt;/p&gt;

&lt;h1 id=&quot;using-roslyn-analysers-as-nuget-packages-in-a-project&quot;&gt;Using Roslyn analysers as NuGet packages in a project&lt;/h1&gt;

&lt;p&gt;This brings us to the second option of using Roslyn analysers, which is to install them as a NuGet package in all projects in the Visual Studio solution.&lt;/p&gt;

&lt;p&gt;Note that Visual Studio/Roslyn will handle that you could have the same analyser installed both as an extension (globally) and as a NuGet package (locally) and this won’t lead to duplicate warnings. However there is a bug where code fixes will be duplicated which is tracked &lt;a href=&quot;https://github.com/dotnet/roslyn/issues/4030&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/nuget.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once installed you will notice the analyser under the new &lt;em&gt;Analysers&lt;/em&gt; section under &lt;em&gt;References&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/references.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And if we look at the content of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csproj&lt;/code&gt; file we will see this:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Analyzer&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Include=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;..\packages\RefactoringEssentials.1.2.0\analyzers\dotnet\RefactoringEssentials.dll&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The downside is that we have to ensure that every new project added to the solution has the analyser NuGet package added to it, but automating that is not that hard (e.g. using pre-commit hooks in Git).&lt;/p&gt;

&lt;h1 id=&quot;configuring-roslyn-analyser-rules-for-a-single-project&quot;&gt;Configuring Roslyn analyser rules for a single project&lt;/h1&gt;

&lt;p&gt;That’s all great, but what if we don’t want to remove &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt; from our fields, because it doesn’t conform to our code style? Or alternatively - we want it to be a hard error, so it conforms to our code style?&lt;/p&gt;

&lt;p&gt;We can edit the current rules set by right clicking on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Analysers&lt;/code&gt; and then changing the warning level:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/ruleset-menu.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/edit.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once saved a new file will shop up in the project &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RoslynAnalysersUsageSample.ruleset&lt;/code&gt; and if we open it we will see that the configuration has been added to the XML:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;RuleSet&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rules for RoslynAnalysersUsageSample&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Description=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Code analysis rules for RoslynAnalysersUsageSample.csproj.&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ToolsVersion=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;14.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;Rules&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;AnalyzerId=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;RefactoringEssentials&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;RuleNamespace=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;RefactoringEssentials&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Rule&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;RECS0145&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Action=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Rules&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/RuleSet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the same Rules Set file that we know from previous version of Visual Studio, which used to contain FxCop based rules. However an important note for those familiar with FxCop based Code Analysis rule sets is that all Roslyn analyser rules are enabled by default (in FxCop you had to add the rules explicitly).&lt;/p&gt;

&lt;h1 id=&quot;configuring-roslyn-analyser-rules-for-the-whole-solution&quot;&gt;Configuring Roslyn analyser rules for the whole solution&lt;/h1&gt;

&lt;p&gt;Let’s add a new project to the solution with the Refactoring Essentials NuGet package installed and copy paste the class above into the new project. We will notice that our custom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Error&lt;/code&gt; level for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECS0145&lt;/code&gt; rule is not applied. And that’s because our previous customization only applied for that single project we edited:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/second-project.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To remedy that we need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Move out the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RoslynAnalysersUsageSample.ruleset&lt;/code&gt; file in a more sensible place such as the root of the solution, because it will no longer apply for a single project.&lt;/li&gt;
  &lt;li&gt;Add it to the solution as a “Solution Item”&lt;/li&gt;
  &lt;li&gt;Configure the solution-level Code Analysis to use the rule set for all projects in the solution&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/content/2015-10-06-using-roslyn-analysers/rules.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s it!&lt;/p&gt;

&lt;h1 id=&quot;suppressing-warnings-in-special-cases&quot;&gt;Suppressing warnings in special cases&lt;/h1&gt;

&lt;p&gt;In those rare cases when there is a warning, but there is a valid reason why we have done something the way we have done it the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Diagnostics.CodeAnalysis.SuppressMessage&lt;/code&gt; attribute can be used (or evil evil #pragma).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[SuppressMessage(&quot;Potential Code Quality Issues&quot;, 
                 &quot;RECS0022:A catch clause that catches System.Exception and has an empty body&quot;, 
                 Justification = &quot;This is an explanation why I have suppressed this warning.&quot;)]
void Start()
{
    try {
        throw new NotSupportedException();
    } catch { // warning here, becase the catch is empty
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;continuous-integration&quot;&gt;Continuous Integration&lt;/h1&gt;

&lt;p&gt;No extra work is required if the code analysers are added to the solution as NuGet packages and included under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Analysers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are two things to be aware of though:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You may see build errors if you don’t do a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nuget restore .sln&lt;/code&gt; on the build server before calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msbuild&lt;/code&gt;. It appears the VS build is trying to read analyser info before nuget is able to restore the packages.&lt;/li&gt;
  &lt;li&gt;Roslyn analyser warnings are standard compiler warnings so you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TreatWarningsAsErrors&lt;/code&gt; MsBuild property too.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;final-words&quot;&gt;Final words&lt;/h1&gt;

&lt;p&gt;In this post we have covered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;What are Roslyn Analysers&lt;/li&gt;
  &lt;li&gt;How to use them in a team or individually&lt;/li&gt;
  &lt;li&gt;How to configure them across a project and a solution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope it was useful to you guys. Let me know in the comments!&lt;/p&gt;

</description>
                
                            <pubDate>Sun, 06 Sep 2015 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2015/09/06/using-roslyn-analysers?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2015/09/06/using-roslyn-analysers?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Use a PIN code instead of password on your Surface Pro (or other Windows touch device)</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Here are step instruction on how to replace the Windows login password prompt with a PIN code, especially on those yummy new Windows tablets (I am looking at you Surface Pro 3):&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-32-42.png&quot;&gt;&lt;img class=&quot;aligncenter wp-image-1039 &quot; src=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-32-42.png&quot; alt=&quot;2014-11-21_21-32-42&quot; width=&quot;455&quot; height=&quot;284&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-33-38.png&quot;&gt;&lt;img class=&quot;aligncenter  wp-image-1042&quot; src=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-33-38.png&quot; alt=&quot;2014-11-21_21-33-38&quot; width=&quot;371&quot; height=&quot;267&quot; /&gt;&lt;/a&gt;  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-33-58.png&quot;&gt;&lt;img class=&quot;aligncenter wp-image-1040 &quot; src=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-33-58.png&quot; alt=&quot;2014-11-21_21-33-58&quot; width=&quot;467&quot; height=&quot;654&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-34-33.png&quot;&gt;&lt;img class=&quot;aligncenter wp-image-1041 size-full&quot; src=&quot;http://ivanz.com/wp-content/uploads/2014/11/2014-11-21_21-34-33.png&quot; alt=&quot;2014-11-21_21-34-33&quot; width=&quot;1064&quot; height=&quot;417&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

</description>
                
                            <pubDate>Fri, 21 Nov 2014 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2014/11/21/use-a-pin-code-instead-of-password-on-your-surface-pro-or-other-windows-touch-device/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2014/11/21/use-a-pin-code-instead-of-password-on-your-surface-pro-or-other-windows-touch-device/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>MSpec TeamCity Parallel Runner &amp;#8211; NuGet package change</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Two quick updates:&lt;/p&gt;

&lt;p&gt;The mspec parallel test runner for TeamCity nuget package is now located at: &lt;a href=&quot;https://www.nuget.org/packages/Machine.Specifications.TeamCityParallelRunner/&quot; target=&quot;_blank&quot;&gt;https://www.nuget.org/packages/Machine.Specifications.TeamCityParallelRunner/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This change was required in order to start following the MSpec version numbers and package naming convention.&lt;/p&gt;

&lt;p&gt;The package version as of this moment is 0.9.0, which matches MSpec 0.9.0.&lt;/p&gt;

&lt;p&gt;If you know how to write a .nuspec which can tell NuGet that it should obsolete one package with another packages – do let me know, please.&lt;/p&gt;
</description>
                
                            <pubDate>Sun, 09 Nov 2014 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2014/11/09/mspec-teamcity-parallel-runner-nuget-package-change/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2014/11/09/mspec-teamcity-parallel-runner-nuget-package-change/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Announcing an MSpec Parallel Test Runner for TeamCity (mspec-teamcity-prunner)</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;&lt;a href=&quot;https://github.com/machine/machine.specifications&quot; target=&quot;_blank&quot;&gt;MSpec&lt;/a&gt; is absolutely great – no argument about it. I am using it exclusively in a current project to specify and test top to bottom. However one thing that has been bugging me for a long time is the inability to run tests in parallel on TeamCity. Most Visual Studio tools support it (CodeRush, ReSharper, etc) – why shouldn’t it be possible to do it on the build server? And as test run time kept increasing I finally got fed up and did something about it.&lt;/p&gt;

&lt;p&gt;I am pleased to announce &lt;strong&gt;&lt;a href=&quot;https://github.com/ivanz/mspec-teamcity-prunner&quot; target=&quot;_blank&quot;&gt;mspec-teamcity-prunner.exe&lt;/a&gt;&lt;/strong&gt;. It is a drop-in replacement for the default console runner (mspec.exe) with the major difference that through the &lt;em&gt;–threads N&lt;/em&gt; parameter you can specify the number of assemblies to run in parallel.&lt;/p&gt;

&lt;p&gt;Drop-in replacement means that all you need to do is swap the path to mspec.exe with the one to mspec-teamcity-prunner.exe in your TeamCity Build Step.&lt;/p&gt;

&lt;p&gt;For me this has lead to ~70% reduction in the time it takes to run our MSpec test suite.&lt;/p&gt;

&lt;p&gt;Details on the project and installation instructions/NuGet package here:&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;strong&gt;&lt;a href=&quot;https://github.com/ivanz/mspec-teamcity-prunner&quot; target=&quot;_blank&quot;&gt;https://github.com/ivanz/mspec-teamcity-prunner&lt;/a&gt;&lt;/strong&gt;
&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
</description>
                
                            <pubDate>Sun, 26 Oct 2014 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2014/10/26/announcing-an-mspec-parallel-test-runner-for-teamcity-mspec-teamcity-prunner/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2014/10/26/announcing-an-mspec-parallel-test-runner-for-teamcity-mspec-teamcity-prunner/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Traktor Pro .tsi file format reverse-engineered  &amp;#8211; docs on GitHub</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I’ve reverse-engineered the .tsi binary file format specification, which Traktor Pro by Native Instruments uses to store its Controller Mappings. I am hoping this should open the gates to new power tooling for MIDI controller mapping power tools (Traktor’s own being rather sub-optimal).&lt;/p&gt;

&lt;p&gt;The project, documentation and instructions are here: &lt;strong&gt;&lt;a href=&quot;https://github.com/ivanz/TraktorMappingFileFormat/wiki&quot;&gt;https://github.com/ivanz/TraktorMappingFileFormat/wiki&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Can’t sing enough praises of &lt;a href=&quot;http://www.sweetscape.com/010editor/&quot; target=&quot;_blank&quot;&gt;010 Editor by SweetScape&lt;/a&gt; which enabled me to write scripts and define data structures incrementally on top of a binary blob.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2014/10/2014-10-20_01-53-45.png&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-1013&quot; src=&quot;http://ivanz.com/wp-content/uploads/2014/10/2014-10-20_01-53-45-300x212.png&quot; alt=&quot;2014-10-20_01-53-45&quot; width=&quot;300&quot; height=&quot;212&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 20 Oct 2014 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2014/10/20/traktor-pro-tsi-file-format-reverse-engineered-docs-on-github/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2014/10/20/traktor-pro-tsi-file-format-reverse-engineered-docs-on-github/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Guide for migrating an ASP.NET MVC Solution to .NET 4.5 and ASP.NET MVC 4</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;You can find a very handy step by step guide for migrating to ASP.NET MVC 4 &lt;a href=&quot;http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253806&quot;&gt;here&lt;/a&gt; . It might seem a bit long, but actually with a few multi-file search and replace and some regex you can do it pretty quickly.&lt;/p&gt;

&lt;p&gt;I just wanted to add a few more tips:&lt;/p&gt;

&lt;h4 id=&quot;migrating-to-aspnet-mvc-4&quot;&gt;Migrating to ASP.NET MVC 4&lt;/h4&gt;

&lt;p&gt;If you are still using bin deployables (“Add Deployable Assembly”) for your current ASP.NET MVC setup – you should remove it and replace it with the &lt;em&gt;AspNetMvc&lt;/em&gt; nuget package.&lt;/p&gt;

&lt;p&gt;If you are using &lt;em&gt;MvcContrib&lt;/em&gt; or &lt;em&gt;MvcFutures&lt;/em&gt; – it’s probably best to update to* MvcContrib.Mvc3-ci *and *Mvc3Futures . *Either case you will have to deal with the clash of extension methods (&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh429726(v=vs.108)&quot;&gt;Html.IdFor, Html.NameFor, etc&lt;/a&gt;) which were previously in Mvc Futures (Microsoft.Web.Mvc.dll) but now are part of the core ASP.NET MVC assembly. Until updated versions of MvcContrib and MvcFutures come out I have resolved this by removing the  using statement from my View’s Web.config for the MvcFutures extensions methods namespace. This however means that you lose tiny things like Html.SubmitButton, which you can easily replace across the whole solution with html code using a Regex.&lt;/p&gt;

&lt;p&gt;Be careful about underwater rocks like&lt;a href=&quot;http://ivanz.com/2012/08/17/heads-up-on-a-hidden-breaking-change-in-asp-net-mvc-4/&quot; title=&quot;Heads up on a hidden breaking change in ASP.NET MVC 4&quot;&gt; this one about the new Date and DateTime editor templates in MVC 4&lt;/a&gt;. Also there seem to be model binding changes to do with &lt;em&gt;DateTime&lt;/em&gt; – so far that has been the major pain in the ass for me.&lt;/p&gt;

&lt;h4 id=&quot;re-targeting-for-net-45&quot;&gt;Re-targeting for .NET 4.5&lt;/h4&gt;

&lt;p&gt;The fastest way to convert all projects is by doing a search and replace across all &lt;em&gt;.csproj files and replace &lt;/em&gt;&lt;TargetFrameworkVersion&gt;v4.0&lt;/TargetFrameworkVersion&gt;  &lt;em&gt;with&lt;/em&gt; &lt;TargetFrameworkVersion&gt;v4.5&lt;/TargetFrameworkVersion&gt; *(or client profile, etc)&lt;/p&gt;

&lt;p&gt;also replace in your Web.config &lt;em&gt;compilation&lt;/em&gt; element &lt;em&gt;targetFramework=”4.0″&lt;/em&gt; with 4.5&lt;/p&gt;

&lt;p&gt;The real issue are the NuGet packages – some have a .NET 4.5 specific version – a good example is Entity Framework. When the project is targeting version 4.0 of the framework and you install/update EF to version 5 you actually end up with EF 4.4 (which doesn’t have support for enums and so on). The only way to solve this is to remove all packages and install them again, which is a massive pain to do manually and unfortunately the current version of NuGet is not of much help there either, but the daily build is. &lt;a href=&quot;http://stackoverflow.com/questions/12006991/retargeting-solution-from-net-4-0-to-4-5-how-to-retarget-the-nuget-packages&quot;&gt;More details about retargeting the NuGet packages are available in this StackOverflow question.&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;a-few-other-notes&quot;&gt;A few other notes&lt;/h4&gt;

&lt;p&gt;Things that I have personally tested and work fine: MiniProfiler works fine with an runtime assembly binding redirect for Entity Framework, ELMAH and Ninject work without any changes. Noticed a small regression in unobtrusive validation and checkboxed when pulling a form with AJAX, but I that ended caused by a jQuery Validation problem.&lt;/p&gt;

&lt;p&gt;Oh and by the way, don’t forget to update your test assemblies *App.config *with the correct assembly redirects if you are running tests against ASP.NET MVC controllers, which use MvcFutures or MvcContrib, because you will end up seeing weird “Type A doesn’t match type A” errors.&lt;/p&gt;

&lt;p&gt;To be honest I haven’t seen noticeable performance improvements with the MVC 4 + .NET 4.5 + EF5 combo so far, but time will tell.&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 20 Aug 2012 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2012/08/20/guide-for-migrating-an-asp-net-mvc-solution-to-net-4-5-and-asp-net-mvc-4/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2012/08/20/guide-for-migrating-an-asp-net-mvc-solution-to-net-4-5-and-asp-net-mvc-4/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Windows 8 Code Weekend: 8-9th September in London &amp;#8211; dev4good</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;div style=&quot;float: right;&quot;&gt;
  &lt;p&gt;
    &lt;img style=&quot;border: 1px solid black; margin-top: 10px; margin-bottom: 10px; float: right;&quot; src=&quot;http://dev4good.net/Media/Default/Page/welcome-to-orchard/weneedmonkey.gif&quot; alt=&quot;&quot; width=&quot;200&quot; height=&quot;166&quot; /&gt; &lt;img style=&quot;clear: right; float: RIGHT;&quot; src=&quot;http://dev4good.net/Media/Default/pdf/microsoft-logo.jpg&quot; alt=&quot;&quot; width=&quot;200&quot; height=&quot;48&quot; /&gt;&lt;img style=&quot;clear: right; display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;http://www.seren.com/html/images/logo/seren_logo.png&quot; alt=&quot;&quot; width=&quot;126&quot; height=&quot;33&quot; /&gt;
  &lt;/p&gt;
  
  &lt;div style=&quot;clear: right; display: block; margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;
    &lt;span style=&quot;font-family: &apos;arial black&apos;, &apos;avant garde&apos;; font-size: large;&quot;&gt;TheGivingLab.Org&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We’re running a second dev4good event in collaboration with TheGivingLab.org and Givey this year to bring together talented thinkers, designers and coders from around the UK to work on some real-world issues faced by UK charities. The technology theme for the event is &lt;strong&gt;Windows 8&lt;/strong&gt;, but &lt;span style=&quot;text-decoration: underline;&quot;&gt;&lt;strong&gt;no prior knowledge&lt;/strong&gt;&lt;/span&gt; of Windows 8 app development is required.&lt;/p&gt;

&lt;p&gt;Microsoft will present &lt;em&gt;Windows 8 Developer Overview&lt;/em&gt;, showing us the technical perspective. Seren will be next up talking about how to design a great experience on Windows 8. (Full details of these sessions will follow shortly.) TheGivingLab.org, will be sharing charity projects, apps and experiences they’d like inspire you with and sharing learnings from their first tech experiment www.seethedifference.org. We may even work on one of your own ideas – if you’ve got one.&lt;/p&gt;

&lt;p&gt;Our goals for the weekend are simple. We want to learn how to create Windows 8 apps that could change the way people live their lives – and then we’re going to spend the rest of the time doing it!&lt;/p&gt;

&lt;div&gt;
  &lt;p&gt;
    If you are a software developer (on any platform), designer, computing student, or are just interested in help out – then we need you. It’s going to be a real challenge – and sleep will be optional. Are you up for it? If you are, the event page is &lt;a href=&quot;http://www.dev4good.net/windows-8-code-weekend-2012&quot;&gt;here&lt;/a&gt;.
  &lt;/p&gt;
  
  &lt;p&gt;
    Remember, this is a not-for-profit event being run by volunteers, so you won’t be paid for the work you do. You will, however, get to meet and work with some of the smartest developers and designers in the UK – all while doing some real good for society.
  &lt;/p&gt;
  
  &lt;p&gt;
    We’re also looking for sponsorship for this event, so please &lt;a href=&quot;http://dev4good.net/contact&quot; target=&quot;_blank&quot;&gt;contact us&lt;/a&gt; if you believe you can help in any way.
  &lt;/p&gt;
  
  &lt;p&gt;
    If you are a UK charity or a community based organisation, then &lt;a href=&quot;http://dev4good.net/bit-for-charity&quot;&gt;have a look at what we could do for you&lt;/a&gt; or &lt;a href=&quot;http://dev4good.net/contact&quot; target=&quot;_blank&quot;&gt;contact us&lt;/a&gt; directly. Thank you.
  &lt;/p&gt;
  
  &lt;p&gt;
    We need you help &amp;#8211; so spread the word, &lt;a href=&quot;http://www.dev4good.net/Media/Default/pdf/win_8_poster.pdf&quot; target=&quot;_blank&quot;&gt;download our poster&lt;/a&gt; and put it up where you work, send it to your friends.
  &lt;/p&gt;
  
  &lt;p&gt;
    &lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;http://www.dev4good.net/Media/Default/pdf/poster.jpg&quot; alt=&quot;&quot; width=&quot;442&quot; height=&quot;624&quot; /&gt;
  &lt;/p&gt;
&lt;/div&gt;
</description>
                
                            <pubDate>Fri, 17 Aug 2012 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2012/08/17/windows-8-code-weekend-8-9th-september-in-london-dev4good/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2012/08/17/windows-8-code-weekend-8-9th-september-in-london-dev4good/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Heads up on a hidden breaking change in ASP.NET MVC 4</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;If you, like me, are using an Editor Template for DateTime and use the &lt;em&gt;DataTypeAttribute&lt;/em&gt; with either or &lt;em&gt;DataType.Date&lt;/em&gt; and &lt;em&gt;DataType.DateTime&lt;/em&gt; in ASP.NET MVC 2 or 3 and happen to upgrade to ASP.NET MVC 4 &lt;strong&gt;be aware!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ASP.NET MVC 4 introduces two new internal editor templates for properties marked as &lt;em&gt;DataType.Date&lt;/em&gt; and &lt;em&gt;DataType.DateTime &lt;/em&gt;to render HTML5 input types (date and datetime accordingly).&lt;/p&gt;

&lt;p&gt;The unexpected side-effect of this is that if you were previously capturing all &lt;em&gt;DateTime *type editing through a *DateTime&lt;/em&gt; editor template now if your property is marked as &lt;em&gt;DataType.Date&lt;/em&gt; ASP.NET MVC 4 will use the new internal &lt;em&gt;Date&lt;/em&gt; editor template instead of your *DateTime *editor template.&lt;/p&gt;

&lt;p&gt;The solution is to provide a &lt;em&gt;Date.cshtml *editor template along your&lt;/em&gt; DateTime.cshtml* editor template.&lt;/p&gt;
</description>
                
                            <pubDate>Fri, 17 Aug 2012 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2012/08/17/heads-up-on-a-hidden-breaking-change-in-asp-net-mvc-4/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2012/08/17/heads-up-on-a-hidden-breaking-change-in-asp-net-mvc-4/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Disable archive instead of delete mail in Gmail on iPhone/iPad</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;For a long time the default and very painful behaviour between the integration of iOS devices (iPhone/iPad) and Gmail’s Exchange support (required for push email) has been that whenever you delete an email it will actually archive it instead (put it in the “All Mail” folder).&lt;/p&gt;

&lt;p&gt;Like me many people hated that and have been complaining for a long time on Google’s Forum, Groups and Feedback sites. I have personally been using a “delete” label and moving messages there to delete later on my PC.&lt;/p&gt;

&lt;p&gt;No more!&lt;/p&gt;

&lt;p&gt;Apparently Google have quietly (I have not seen an announcement?) added a feature to disable this annoying behavior and deleted mail will end up in Gmail’s Trash folder instead.&lt;/p&gt;

&lt;p&gt;To enable it you have to open the Google Sync settings page from your mobile device at &lt;a href=&quot;http://m.google.com/sync&quot;&gt;http://m.google.com/sync&lt;/a&gt; . Note that &lt;span style=&quot;text-decoration: underline;&quot;&gt;you can not access this page from your computer&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;In there you will see a new checkbox saying something like “Move delete mail to Trash”. Tick, save, boom.&lt;/p&gt;

&lt;p&gt;P.S: BTW for those of you who don’t know this is also the place where you pick which Google Calendar Calendars to make available for syncing on your device.&lt;/p&gt;
</description>
                
                            <pubDate>Sun, 22 Apr 2012 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2012/04/22/disable-archive-instead-of-delete-mail-in-gmail-on-iphoneipad/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2012/04/22/disable-archive-instead-of-delete-mail-in-gmail-on-iphoneipad/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>dev4good &amp;#8211; Developing for a Better World</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/charity-portal-screenshot.png&quot;&gt;&lt;br /&gt;
&lt;/a&gt;Last weekend (2-3 July) I attended the first ever &lt;a href=&quot;http://dev4good.net&quot;&gt;dev4good&lt;/a&gt; – a charity hackathon where developers try to solve charity problems in a weekend. It took place in Hammersmith, London in a amazing venue on the riverside:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/IMG_1305.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-large wp-image-945&quot; title=&quot;IMG_1305&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/IMG_1305-1024x764.jpg&quot; alt=&quot;&quot; width=&quot;620&quot; height=&quot;462&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three charities came to use with the following problems:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;www.hopeandplay.org&quot;&gt;Hope and Play&lt;/a&gt; were looking for a way to locate and manage resources. And allow other charities or people to do the same.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;www.ministryofstories.org&quot;&gt;The Ministry of Stories&lt;/a&gt; were looking for a way to get more young people writing stories and publishing these to the world. All while helping to generate a little more cash along the way.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;www.craftanddesigncouncil.org.uk&quot;&gt;The Design and Craft Council&lt;/a&gt; want to be able to automate their awards processes.&lt;/p&gt;

&lt;p&gt;We were about 25 people and were able to split in three teams. Here is a video of my team explaining what we are planning to achieve for the Hope and Play project (I am the one speaking first):&lt;/p&gt;

&lt;p&gt;Basically we wanted to create a proof of concept system that:&lt;/p&gt;

&lt;ol id=&quot;internal-source-marker_0.27231994923204184&quot;&gt;
  &lt;li&gt;
    Provides a central web portal to aggregate information and also allow charities to communicate what projects they are running, and in which locations.
  &lt;/li&gt;
  &lt;li&gt;
    Allows charities to communicate in real-time work and achievements on their projects via the web portal, Twitter or mobile text messages (SMS).
  &lt;/li&gt;
  &lt;li&gt;
    Enable charities and individuals to advertise their available and required resources (human power, building material, etc) and its location.
  &lt;/li&gt;
  &lt;li&gt;
    Provides a means for charities to discover information on the web relevant to their projects and location.
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the end it looked like this (test data, which probably doesn’t illustrate perfectly the usage):&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/charity-portal-screenshot.png&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;charity portal screenshot&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/charity-portal-screenshot.png&quot; alt=&quot;&quot; width=&quot;1003&quot; height=&quot;841&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
My team worked great together. We were able to quickly split the work so that everyone has something of interest to do. It was very exciting to see how we are making progress during our scrum stand ups:&lt;br /&gt;
&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/WP_000815.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-large wp-image-950&quot; title=&quot;WP_000815&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/WP_000815-1024x768.jpg&quot; alt=&quot;&quot; width=&quot;620&quot; height=&quot;465&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
At the start of the event we decided that we are going to use Git for source control and GitHub for hosting. Apart from me only one other person had used Git before, but I was happy to help out each of the guys and keep them going during the event. As you can see from the below GitHub commits timeline we were quite effective in working in parallel:&lt;br /&gt;
&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/Weekend-Timeline.png&quot;&gt;&lt;img class=&quot;aligncenter size-large wp-image-951&quot; title=&quot;Weekend Timeline&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/Weekend-Timeline-1024x105.png&quot; alt=&quot;&quot; width=&quot;620&quot; height=&quot;63&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
I think 99.9% of us were running Windows and using Bash or Cmd was absolutely not an option for the non-Gitters who had mainly experience with TFS or SVN. Most new Gitters used Tortoise Git, but that was still confusing as it required understanding of how everything works. Only later I learned about SmartGit and in retrospect I think we should have used that instead.&lt;/p&gt;

&lt;p&gt;As you’ll hear on the video initially we planned to use Orchard CMS, but after some research and poking around I was personally disappointed to find out how over-complex and over-engineered Orchard is. So we dumped it and went for plain old ASP.NET MVC 3 and non-POCO Entity Framework, which worked out quite well – after all it was just meant to be proof of concept.&lt;/p&gt;

&lt;p&gt;All in all I had great fun during the weekend. I also met some great people, who I am looking forward to seeing and work with again in the future – probably during GiveCamp UK in October!&lt;/p&gt;

&lt;p&gt;At the end of the weekend it turned out that most people voted for me as the most supportive and helpful developer during the weekend, so I won the grand prize – a Kinect. I wasn’t expecting this at all and very grateful to everyone and very happy that I was able to help people out. Thanks guys!&lt;br /&gt;
&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/Kinect-Prize.jpeg&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-953&quot; title=&quot;Kinect Prize&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/Kinect-Prize-300x224.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;224&quot; /&gt;&lt;/a&gt;And here is an end of event photo of team dev4good:&lt;br /&gt;
&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/WP_000825.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-large wp-image-954&quot; title=&quot;WP_000825&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/WP_000825-1024x768.jpg&quot; alt=&quot;&quot; width=&quot;620&quot; height=&quot;465&quot; /&gt;&lt;/a&gt;Great job guys!&lt;/p&gt;

&lt;p&gt;Also big thanks to our sponsors:&lt;br /&gt;
&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/sponsors.png&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-955&quot; title=&quot;sponsors&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/07/sponsors-300x179.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;179&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h3&gt;

&lt;p&gt;We are in the process of moving and merging the team repositories in a central one in GitHub. I am looking forward to get in touch with some charities to discuss and get feedback for our proof of concept Charity Portal and its eventual real-life practical application.&lt;/p&gt;

&lt;p&gt;Next also is GiveCamp UK! I am also tempted to go to Startup Weekend Lonodon, but I’ll see about that.&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 04 Jul 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/07/04/dev4good-developing-for-a-better-world/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/07/04/dev4good-developing-for-a-better-world/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Featured on the home page of ASP.NET</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Really exciting for me is that a few days ago my series on &lt;a href=&quot;http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/&quot;&gt;Editing Variable Length Reorderable Collections in ASP.NET MVC&lt;/a&gt; got featured on the home page of the ASP.NET web site. I just wanted to say thank you to the person who decided to share it with the community. Here is a screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/07/Ivan-Zlatev-ASP.NET-Home-Page.png&quot;&gt;&lt;img src=&quot;http://ivanz.com/wp-content/uploads/2011/07/Ivan-Zlatev-ASP.NET-Home-Page.png&quot; alt=&quot;&quot; title=&quot;Ivan Zlatev ASP.NET Home Page&quot; width=&quot;1157&quot; height=&quot;1023&quot; class=&quot;aligncenter size-full wp-image-932&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Sun, 03 Jul 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/07/03/featured-on-the-home-page-of-asp-net/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/07/03/featured-on-the-home-page-of-asp-net/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Editing Variable Length Reorderable Collections in ASP.NET MVC &amp;#8211; Part 3: Knockout JS</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;&lt;a href=&quot;http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/&quot; title=&quot;Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 1&quot;&gt;In Part 1 of this series&lt;/a&gt; I discussed the problems that we face when implementing an editor for a variable length, reorderable collection and reuse our server-side ASP.NET MVC views, model binding and validation.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/&quot; title=&quot;Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 2&quot;&gt;In Part 2 of this series&lt;/a&gt; I began moving some aspects of the collection editing to the client-side with jQuery Templates, but we realized that it’s not good enough, because instead of dealing with data we are juggling with our ASP.NET MVC views generated HTML.&lt;/p&gt;

&lt;p&gt;In this final Part 3 of the series I want to move the collection editing completely to the client-side using the &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;Knockout JS library&lt;/a&gt; JavaScript library. I will look at:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Knockout JS data-binding and tempalting&lt;/li&gt;
  &lt;li&gt;JSON Form (data really – no form) submission&lt;/li&gt;
  &lt;li&gt;jQuery Client-Side Validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will re-implement our sample collection editor and it is going to look exactly the same as it did before. Before I begin just a reminder that &lt;a href=&quot;http://github.com/ivanz/ASP.NET-MVC-Collection-Editing&quot;&gt;all of the source code is available on GitHub as a Visual Studio solution&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;what-is-knockout-js&quot;&gt;What is Knockout JS?&lt;/h4&gt;

&lt;p&gt;I am going to quote its creator (Steven Sanderson) from his introductory post, where he provides &lt;a href=&quot;http://blog.stevensanderson.com/2010/07/05/introducing-knockout-a-ui-library-for-javascript/&quot;&gt;a very good overview&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Knockout is a JavaScript library that makes it easier to create rich, desktop-like user interfaces with JavaScript and HTML, using &lt;em&gt;observers *to make your UI automatically stay in sync with an underlying data model. It works particularly well with the MVVM pattern, offering &lt;/em&gt;declarative bindings *somewhat like Silverlight but without the browser plugin.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I suggest you read the above linked post or checkout the Knockout JS web site to learn more about it, but to quickly summarize how it works:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A JavaScipt view model is defined that holds all the data. All the data properties are initialized as (or wrapped in) observable values and arrays.&lt;/li&gt;
  &lt;li&gt;HTML elements can be data-bound to a property (similar to WinForms/XAML(WPF/Silverlight)) from the view model using the *data-bind *attribute syntax. We can bind an input’s value, a span’s text, etc. to a view model property.&lt;/li&gt;
  &lt;li&gt;Whenever a value/or array changes the data-binding kicks in and the HTML element are automatically updated.&lt;/li&gt;
  &lt;li&gt;Knockout uses jQuery and supports templating via jQuery Templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;our-sample&quot;&gt;Our Sample&lt;/h4&gt;

&lt;p&gt;To understand this lets jump straight into our sample app.&lt;/p&gt;

&lt;p&gt;I have added a third edit option to our sample:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-856&quot; title=&quot;knockout-edit&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit.png&quot; alt=&quot;&quot; width=&quot;304&quot; height=&quot;223&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;which surprise, surprise looks exactly the same as in the previous iteration. Apart from one extra feature – the favourite movies counter I’ve added to give you a hint of the power of Knockout JS:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-screen.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-857&quot; title=&quot;knockout-edit-screen&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-screen.png&quot; alt=&quot;&quot; width=&quot;571&quot; height=&quot;383&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;view-and-viewmodel&quot;&gt;View and ViewModel&lt;/h4&gt;

&lt;p&gt;Let’s firstly look at the first iteration of our view model implementation:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
var viewModel = {
    Id: ko.observable(@Model.Id),
    Name: ko.observable(&quot;@Model.Name&quot;),
    FavouriteMovies: ko.observableArray(@Html.Json(@Model.FavouriteMovies) || []),

    maxMovies: 10,
    
    addMovie: function() {
        viewModel.FavouriteMovies.push(@Html.Json(new Movie()));
    },

    removeMovie: function(movie) {
        ko.utils.arrayRemoveItem(viewModel.FavouriteMovies, movie);
    }
};

$(function () {
    ko.applyBindings(viewModel);
});
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;We:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Serialize our ASP.NET MVC &lt;em&gt;User&lt;/em&gt; Model to JSON (&lt;em&gt;Id&lt;/em&gt;, &lt;em&gt;Name&lt;/em&gt;, &lt;em&gt;FavouriteMovies&lt;/em&gt;). &lt;em&gt;Html.Json&lt;/em&gt; is a custom Html helper that simply wraps a JSON serializer – you can &lt;a href=&quot;https://github.com/ivanz/ASP.NET-MVC-Collection-Editing/blob/master/CollectionEditing/Infrastructure/JsonHtmlExtensions.cs&quot;&gt;see it in the source code&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Wrap its values in Knockout observables and then once the page is loaded we initialize Knockout JS with our model&lt;/li&gt;
  &lt;li&gt;Define some add/remove movie methods to edit the FavouriteMovies collection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What’s crucial here is that we are not dealing with nor manipulating HTML markup&lt;/strong&gt;, which is something that we were doing heavily in the previous parts.&lt;/p&gt;

&lt;p&gt;When processed server-side the above view model will look like roughly like this in the browser:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;var viewModel = {
        Id: ko.observable(1),
        Name: ko.observable(&quot;Ivan Zlatev&quot;),
        FavouriteMovies: ko.observableArray([{&quot;Title&quot;:&quot;Movie 1&quot;,&quot;Rating&quot;:5},
                                                           {&quot;Title&quot;:&quot;Movie 2&quot;,&quot;Rating&quot;:10},
                                                           {&quot;Title&quot;:&quot;Movie 3&quot;,&quot;Rating&quot;:12}] || []),

        maxMovies: 10,

        addMovie: function() {
            viewModel.FavouriteMovies.push({&quot;Title&quot;:null,&quot;Rating&quot;:0});
        },

        removeMovie: function(movie) {
            ko.utils.arrayRemoveItem(viewModel.FavouriteMovies, movie);
        }
}&lt;/pre&gt;

&lt;p&gt;Let’s look at the first iteration of our edit view (&lt;em&gt;EditKnockoutJS.cshtml&lt;/em&gt;) to better understand how does Knockout help us:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;@model CollectionEditing.Models.User
@{ ViewBag.Title = &quot;Edit My Account With Knockout JS&quot;; }

&amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/jquery.validate.min.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/jQuery.tmpl.min.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/knockout-1.2.1.debug.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/knockout.jQueryUI-sortable.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;h2&amp;gt;Edit&amp;lt;/h2&amp;gt;

@using (Html.BeginForm(&quot;EditKnockoutJS&quot;, &quot;User&quot;, FormMethod.Post, new { id = &quot;profileEditorForm&quot; })) {
    @Html.ValidationSummary(false)
    &amp;lt;fieldset&amp;gt;
        &amp;lt;legend&amp;gt;My Details&amp;lt;/legend&amp;gt;

        &amp;lt;input name=&quot;userId&quot; type=&quot;hidden&quot; data-bind=&quot;value: Id&quot;/&amp;gt;

        &amp;lt;label for=&quot;name&quot;&amp;gt;Name:&amp;lt;/label&amp;gt;
        &amp;lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot; data-bind=&quot;value: Name&quot; /&amp;gt;
    &amp;lt;/fieldset&amp;gt;
    
    &amp;lt;fieldset&amp;gt;
        &amp;lt;legend&amp;gt;My Favourite Movies&amp;lt;/legend&amp;gt;

        &amp;lt;ul id=&quot;moviesEditor&quot; style=&quot;list-style-type: none&quot;
            data-bind=&quot;template: { name: &apos;moviesTemplate&apos;, data: FavouriteMovies }, 
                       sortableList: viewModel.FavouriteMovies&quot; &amp;gt;
        &amp;lt;/ul&amp;gt;
        &amp;lt;p&amp;gt;You have &amp;lt;span data-bind=&quot;text: FavouriteMovies().length&quot;&amp;gt;&amp;lt;/span&amp;gt; favourite movies.&amp;lt;/p&amp;gt;

        &amp;lt;script id=&quot;moviesTemplate&quot; type=&quot;text/x-jquery-template&quot;&amp;gt;
            
                &amp;lt;li data-bind=&quot;sortableItem: movie&quot;&amp;gt;
                    &amp;lt;div data-bind=&quot;template: { name: &apos;movieTemplate&apos;, data: movie }&quot;&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;/li&amp;gt;
            
        &amp;lt;/script&amp;gt;

        &amp;lt;script id=&quot;movieTemplate&quot; type=&quot;text/x-jquery-template&quot;&amp;gt;
            &amp;lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&amp;gt;

            &amp;lt;label&amp;gt;Title:&amp;lt;/label&amp;gt;
            &amp;lt;input type=&quot;text&quot; data-bind=&quot;value: Title&quot;/&amp;gt;

            &amp;lt;label&amp;gt;Rating:&amp;lt;/label&amp;gt;
            &amp;lt;input type=&quot;text&quot; data-bind=&quot;value: Rating&quot;/&amp;gt;

            &amp;lt;a href=&quot;#&quot; data-bind=&quot;click: function() { viewModel.removeMovie(this); }&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;
        &amp;lt;/script&amp;gt;
    
        &amp;lt;button data-bind=&quot;click: addMovie, enable: FavouriteMovies().length &amp;lt; maxMovies&quot;&amp;gt;Add another&amp;lt;/button&amp;gt;
    &amp;lt;/fieldset&amp;gt;

    &amp;lt;p&amp;gt;
        &amp;lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&amp;gt;
        &amp;lt;a href=&quot;/&quot;&amp;gt;Cancel&amp;lt;/a&amp;gt;
    &amp;lt;/p&amp;gt;
}&lt;/pre&gt;

&lt;p&gt;In our view we use Knockout JS to data-bind our HTML input fields to the data in the viewModel (notice the “&lt;em&gt;data-bind&lt;/em&gt;” attributes).&lt;/p&gt;

&lt;p&gt;For the collection editor:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Similar to Part 2, we have a movie jQuery template, which defines the HTML fields of a movie, but this time we don’t use any ASP.NET MVC helpers.&lt;/li&gt;
  &lt;li&gt;We make the HTML list reorderable via Drag and Drop with the two special &lt;em&gt;sortableList&lt;/em&gt; and &lt;em&gt;sortableItem&lt;/em&gt; bindings.This is a custom Knockout JS binding I’ve created and hosted on &lt;a href=&quot;https://github.com/ivanz/knockout.jQueryUI-sortable.js/blob/master/knockout.jQueryUI-sortable.js&quot;&gt;GitHub here&lt;/a&gt;. Behind the scenes it magically creates a JQuery UI Sortable keeps our &lt;em&gt;viewModel.FavouriteMovies&lt;/em&gt; collection in sync when the widget changes.&lt;/li&gt;
  &lt;li&gt;We limit the number of favourite movies a user can add via the “Add Another” button to ten by using a “&lt;em&gt;enabled&lt;/em&gt;” binding with a boolean expression. Behind the scenes Knockout JS will manage the state of the button and toggle between enabled/disabled depending on the evaluated value of the expression.&lt;/li&gt;
  &lt;li&gt;Finally we data-bind a &lt;em&gt;span&lt;/em&gt; element to display the current number of favourite movies the user has added. Again, this is something that Knockout will keep up to date for us.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Right now with this viewModel and that view we have a working drag and drop add/remove favourite movies editor. What we are still missing however is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Form submission and server-side handling&lt;/li&gt;
  &lt;li&gt;Form validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;form-submission-and-handling&quot;&gt;Form Submission and Handling&lt;/h4&gt;

&lt;p&gt;Let’s add some more code to our view model and view to handle form submission.&lt;/p&gt;

&lt;p&gt;Firstly we are going to implement a save function in our view model. Because we are no longer using ASP.NET model views, we can’t simply submit the form as is – the “standard” form values based ASP.NET MVC model binding won’t work properly and especially so for the collection editing part.&lt;/p&gt;

&lt;p&gt;Thankfully starting from version 3 ASP.NET MVC supports out of the box JSON model binding. It kicks in if the HTTP request Content-Type is set to “application/json”. So instead of using form submission we are going to post our view model data via an AJAX post request to our MVC action, containing the data in JSON serialized form:&lt;/p&gt;

&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;var viewModel = {
       ... snip ...

        saveFailed: ko.observable(false),

        // Returns true if successful
        save: function()
        {
            var saveSuccess = false;
            viewModel.saveFailed(false);

            // Executed synchronously for simplicity
            jQuery.ajax({
                type: &quot;POST&quot;,
                url: &quot;@Url.Action(&quot;EditKnockoutJS&quot;, &quot;User&quot;)&quot;,
                data: ko.toJSON(viewModel),
                dataType: &quot;json&quot;,
                contentType: &quot;application/json&quot;,
                success: function(returnedData) {
                    saveSuccess = returnedData.Success || false;
                    viewModel.saveFailed(!saveSuccess);
                },
                async: false
            });

            return saveSuccess;
        }
};&lt;/pre&gt;

&lt;p&gt;Then we will suppress the default form submission behaviour and replace it with our own:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;p&amp;gt;
    &amp;lt;input type=&quot;submit&quot; value=&quot;Save&quot; 
             data-bind=&quot;click: function() { viewModel.save(); return false; }&quot;/&amp;gt;
    &amp;lt;a href=&quot;/&quot;&amp;gt;Cancel&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;
    
&amp;lt;p data-bind=&quot;visible: saveFailed&quot; class=&quot;error&quot;&amp;gt;A problem occurred saving the data.&amp;lt;/p&amp;gt;&lt;/pre&gt;

&lt;p&gt;Note that I have added a new “&lt;em&gt;saveFailed&lt;/em&gt;” property in the viewModel which is set by &lt;em&gt;save()&lt;/em&gt;. I have also used a “&lt;em&gt;visible&lt;/em&gt;” data binding on the value of that property to display the error message paragraph only if the save operation has failed.&lt;/p&gt;

&lt;p&gt;Now let’s also look at the MVC action to handle the form submission:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;[HttpPost]
public ActionResult EditKnockoutJS(User user)
{
    FormResponseData responseData = new FormResponseData() {
        Success = false
    };

    if (this.ModelState.IsValid) {
        CurrentUser = user;
        responseData.Success = true;
    }

    return Json(responseData);
}

class FormResponseData {
    public bool Success { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Pretty simple action, which just validates the Model using our validation rules/data annotations and returns a &lt;em&gt;FormReponseData&lt;/em&gt; object serialized to JSON, which contains a Success flag expected by the client side.&lt;/p&gt;

&lt;p&gt;We can now persist our view model and also use our server-side model validation to prevent the client from doing nasty things:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-server-validation.png&quot;&gt;&lt;img src=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-server-validation.png&quot; alt=&quot;&quot; title=&quot;knockout-edit-server-validation&quot; width=&quot;558&quot; height=&quot;207&quot; class=&quot;aligncenter size-full wp-image-905&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are not done just yet. Because we no longer use the ASP.NET html helpers we no longer pull the server-side validation error messages and are currently left with the generic “Something went wrong.” error message. This isn’t exactly nice nor user friendly. We can solve this by the use of client-side JavaScript based validation. Remember that we should never ever rely solely on the client-side (and we don’t in our case).&lt;/p&gt;

&lt;h4 id=&quot;client-side-validation&quot;&gt;Client-Side Validation&lt;/h4&gt;

&lt;p&gt;Unfortunately at the time of writing I couldn’t find anything that validates against the Knockout JS viewModel instead of the HTML markup, so I had to resort to &lt;a href=&quot;http://docs.jquery.com/Plugins/validation&quot;&gt;jQuery Validation&lt;/a&gt; for the client-side validation. The problem with that is that we need to ensure that we have set proper unique “name” attributes on our form fields and especially so for our collection editor elements.&lt;/p&gt;

&lt;p&gt;Fortunately Knockout JS already has a binding for that called the “&lt;em&gt;uniqueName&lt;/em&gt; binding”, so all we have to do is add that to our favourite movie collection editor fields like I’ve showed below and don’t worry about generating them ourselves. This is great, because as you saw in Part 2 injecting a unique name during jQuery template evaluation is relatively tricky.&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;script id=&quot;movieTemplate&quot; type=&quot;text/x-jquery-template&quot;&amp;gt;
    &amp;lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&amp;gt;

    &amp;lt;label&amp;gt;Title:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&quot;text&quot; data-bind=&quot;value: Title, uniqueName: true&quot; class=&quot;required&quot;/&amp;gt;

    &amp;lt;label&amp;gt;Rating:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&quot;text&quot; data-bind=&quot;value: Rating, uniqueName: true&quot; class=&quot;required&quot;/&amp;gt;

    &amp;lt;a href=&quot;#&quot; data-bind=&quot;click: function() { viewModel.removeMovie(this); }&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;There are multiple ways we can use jQuery Validation and I have decided to go for the simplest declarative one, where we decorate our fields with extra attributes to describe the value constraints that we want to enforce. Let’s update the above fields to make the &lt;em&gt;Title&lt;/em&gt; and &lt;em&gt;Rating&lt;/em&gt; required:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;label&amp;gt;Title:&amp;lt;/label&amp;gt;
&amp;lt;input type=&quot;text&quot; data-bind=&quot;value: Title, uniqueName: true&quot; class=&quot;required&quot;/&amp;gt;

&amp;lt;label&amp;gt;Rating:&amp;lt;/label&amp;gt;
&amp;lt;input type=&quot;text&quot; data-bind=&quot;value: Rating, uniqueName: true&quot; class=&quot;required&quot;/&amp;gt;&lt;/pre&gt;

&lt;p&gt;Finally let’s plug-in jQuery Validation. To do that we will remove the previous submit button handler and use jQuery Validation instead:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;... snip... 

        &amp;lt;input type=&quot;submit&quot; value=&quot;Save&quot;/&amp;gt;

... snip... 

&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    $(function () {
        ko.applyBindings(viewModel);

        $(&quot;#profileEditorForm&quot;).validate({
            submitHandler: function(form) {
                if(viewModel.save())
                    window.location.href = &quot;/&quot;;

                return false;
            }
        });
    });
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;Which gives us nice per-field validation error messages as we type:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-client-validation.png&quot;&gt;&lt;img src=&quot;http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-client-validation.png&quot; alt=&quot;&quot; title=&quot;knockout-edit-client-validation&quot; width=&quot;676&quot; height=&quot;276&quot; class=&quot;aligncenter size-full wp-image-909&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/ivanz/ASP.NET-MVC-Collection-Editing&quot;&gt;Download all of the source code from GitHub as a Visual Studio solution.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this part we looked at Knockout JS and how great it is in terms of helping us avoid manipulation of HTML markup among many other things. This is generally something that can get really messy quickly and become hard to maintain and track. We also looked at how it helps us neatly solve our collection editing problem without having to worry about practically anything. In the expense of the sacrifice of our Html helpers and partial views, etc we get a lot of flexibility on the client side to add more interactivity in a neat and clean way.&lt;/p&gt;

&lt;h4 id=&quot;final-words&quot;&gt;Final Words&lt;/h4&gt;

&lt;p&gt;If you have a simple collection editing scenario and you are heavily reliant on your ASP.NET MVC views, partial views, editors and displays the approach documented in &lt;a href=&quot;http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/&quot;&gt;Part 1&lt;/a&gt; should be sufficient. And if pulling in new entries/rows via AJAX is not an option (e.g. for speed, performance or any other reasons) you can pull in &lt;a href=&quot;http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/&quot;&gt;Part 2&lt;/a&gt;. However IMHO the better solution most of the time is to use Knockout JS and what I have described in this part as it opens the doors for more complex client-side interactions in a neat and clean way.&lt;/p&gt;

&lt;p&gt;Thank you for reading the series. I will appreciate your feedback in the comments!&lt;/p&gt;

</description>
                
                            <pubDate>Wed, 29 Jun 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Custom Knockout JS binding for jQuery UI Sortable</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;For the work in progress Part 3 of my &lt;a href=&quot;http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/&quot;&gt;Editing Variable Length Reorderable Collections in ASP.NET MVC&lt;/a&gt; blog series I have created a custom Knockout JS binding that keeps a Knockout JS observable array in sync with a jQuery UI sortable.&lt;/p&gt;

&lt;p&gt;It’s available here:&lt;/p&gt;

&lt;p&gt;Basic usage is to use a &lt;em&gt;sortableList&lt;/em&gt; binding on the &lt;em&gt;ul&lt;/em&gt; which you want to make a jQuery Sortable and then a &lt;em&gt;sortableItem&lt;/em&gt; binding for each sortable item (&lt;em&gt;li&lt;/em&gt;) in the list like that:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;ul data-bind=&quot;sortableList: yourObservableArray&quot; &amp;gt; 
     
        &amp;lt;li data-bind=&quot;sortableItem: arrayItem&quot;&amp;gt;&amp;lt;/li&amp;gt; 
     
&amp;lt;/ul&amp;gt;&lt;/pre&gt;

&lt;p&gt;Live example (if you are reading this in a feed reader you will need to open the blog post properly to see this):&lt;/p&gt;

&lt;!-- iframe plugin v.3.0 wordpress.org/plugins/iframe/ --&gt;

</description>
                
                            <pubDate>Mon, 27 Jun 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 2: jQuery Templates</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;&lt;a href=&quot;http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/&quot; title=&quot;Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 1&quot;&gt;In Part 1 of this series&lt;/a&gt; I discussed the problems that we face when implementing an editor for a variable length, reorderable collection and reuse our server-side ASP.NET MVC views, model binding and validation. And while the solution provided in Part 1 is nice and clean (and I personally use it in a few projects) one field for improvement in true Agile Blogging fashion is to find a way to remove the AJAX request we use for fetching new editor rows.&lt;/p&gt;

&lt;p&gt;One way to bring this completely to the client side is by the use of &lt;a href=&quot;http://api.jquery.com/category/plugins/templates/&quot;&gt;jQuery Template&lt;/a&gt; (or any other JavaScript templating engine/library).&lt;/p&gt;

&lt;p&gt;A reminder of what our editor looks like before I begin and a second remind that the source code is available on &lt;a href=&quot;http://github.com/ivanz/ASP.NET-MVC-Collection-Editing&quot;&gt;GitHub&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/image3.png&quot;&gt;&lt;img class=&quot;size-full wp-image-780 aligncenter&quot; title=&quot;Sample Editor&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/image3.png&quot; alt=&quot;&quot; width=&quot;550&quot; height=&quot;435&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start with I have added a second link to our sample’s home page titled “Edit with jQuery templates”:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/home-jquery.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-803&quot; title=&quot;Home Page of the sample&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/home-jquery.png&quot; alt=&quot;&quot; width=&quot;298&quot; height=&quot;202&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Corresponding controller actions:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public ActionResult EditJQueryTemplate()
{
    return View(CurrentUser);
}

[HttpPost]
public ActionResult EditJQueryTemplate(User user)
{
    if (!this.ModelState.IsValid)
        return View(user);

    CurrentUser = user;
    return RedirectToAction(&quot;Display&quot;);
}&lt;/pre&gt;

&lt;p&gt;And a new editor view (&lt;em&gt;EditJQueryTemplate.cshtml&lt;/em&gt;) which is exactly the same as the one from Part 1 apart from the core editor bit:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; highlight: [16,26]; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;legend&amp;gt;My Favourite Movies&amp;lt;/legend&amp;gt;

@if (Model.FavouriteMovies == null || Model.FavouriteMovies.Count == 0) {
    &amp;lt;p&amp;gt;None.&amp;lt;/p&amp;gt;
}
&amp;lt;ul id=&quot;moviesEditor&quot; style=&quot;list-style-type: none&quot;&amp;gt;
    @if (Model.FavouriteMovies != null) {
        foreach (Movie movie in Model.FavouriteMovies) {
            Html.RenderPartial(&quot;MovieEntryEditor&quot;, movie);
        }
    }
&amp;lt;/ul&amp;gt;
&amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/jQuery.tmpl.min.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;script type=&quot;text/x-jquery-tmpl&quot; id=&quot;movieTemplate&quot;&amp;gt;
    @Html.CollectionItemJQueryTemplate(&quot;MovieEntryEditor&quot;, new Movie())
&amp;lt;/script&amp;gt;

&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    $(function () {
        $(&quot;#moviesEditor&quot;).sortable();
    });

    var viewModel = {
        addNew: function () {
            $(&quot;#moviesEditor&quot;).append($(&quot;#movieTemplate&quot;).tmpl({ index: viewModel._generateGuid() }));
        },

        _generateGuid: function () {
            // Source: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/105074#105074
            return &apos;xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx&apos;.replace(/[xy]/g, function (c) {
                var r = Math.random() * 16 | 0, v = c == &apos;x&apos; ? r : (r &amp;amp; 0x3 | 0x8);
                return v.toString(16);
            });
        }
    };
&amp;lt;/script&amp;gt;
            
&amp;lt;a id=&quot;addAnother&quot; href=&quot;#&quot; onclick=&quot;viewModel.addNew();&quot;&amp;gt;Add another&amp;lt;/a&amp;gt;&lt;/pre&gt;

&lt;p&gt;Note the new &lt;em&gt;@Html.CollectionItemJQueryTemplate&lt;/em&gt; helper, which takes a collection item instance with default values and the unchanged partial view &lt;em&gt;MovieEntryEditor&lt;/em&gt; from Part 1:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;@model CollectionEditing.Models.Movie
           
&amp;lt;li style=&quot;padding-bottom:15px&quot;&amp;gt;
    @using (Html.BeginCollectionItem(&quot;FavouriteMovies&quot;)) {
        &amp;lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&amp;gt;

        @Html.LabelFor(model =&amp;gt; model.Title)
        @Html.EditorFor(model =&amp;gt; model.Title)
        @Html.ValidationMessageFor(model =&amp;gt; model.Title)

        @Html.LabelFor(model =&amp;gt; model.Rating)
        @Html.EditorFor(model =&amp;gt; model.Rating)
        @Html.ValidationMessageFor(model =&amp;gt; model.Rating)

        &amp;lt;a href=&quot;#&quot; onclick=&quot;$(this).parent().remove();&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;
    }
&amp;lt;/li&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Basically the helper renders the partial with an ${$index} jQuery template placeholder for which we supply a GUID at run-time on the client-side when we render the template. The output of the helper looks like this:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;script type=&quot;text/x-jquery-tmpl&quot; id=&quot;movieTemplate&quot;&amp;gt;
&amp;lt;li style=&quot;padding-bottom:15px&quot;&amp;gt;

    &amp;lt;input autocomplete=&quot;off&quot; name=&quot;FavouriteMovies.Index&quot; type=&quot;hidden&quot; value=&quot;${index}&quot; /&amp;gt;

    &amp;lt;img src=&quot;/Content/images/draggable-icon.png&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&amp;gt;

    &amp;lt;label&amp;gt;Title&amp;lt;/label&amp;gt;
    &amp;lt;input name=&quot;FavouriteMovies[${index}].Title&quot; type=&quot;text&quot; value=&quot;&quot; /&amp;gt;

    &amp;lt;label&amp;gt;Rating&amp;lt;/label&amp;gt;
    &amp;lt;input name=&quot;FavouriteMovies[${index}].Rating&quot; type=&quot;text&quot; value=&quot;0&quot; /&amp;gt;

    &amp;lt;a href=&quot;#&quot; onclick=&quot;$(this).parent().remove();&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;Everytime the “Add another” button is pressed this template is rendered using a new GUID index value supplied by the &lt;em&gt;viewModel&lt;/em&gt; class.&lt;/p&gt;

&lt;p&gt;Here is the code of the &lt;em&gt;@Html.CollectionItemJQueryTemplate&lt;/em&gt; helper:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public static MvcHtmlString CollectionItemJQueryTemplate&amp;lt;TModel, TCollectionItem&amp;gt;(this HtmlHelper&amp;lt;TModel&amp;gt; html, 
                                                                                    string partialViewName, 
                                                                                    TCollectionItem modelDefaultValues)
{
    ViewDataDictionary&amp;lt;TCollectionItem&amp;gt; viewData = new ViewDataDictionary&amp;lt;TCollectionItem&amp;gt;(modelDefaultValues);
    viewData.Add(JQueryTemplatingEnabledKey, true);
    return html.Partial(partialViewName, modelDefaultValues, viewData);
}&lt;/pre&gt;

&lt;p&gt;It renders the supplied partial view, but before that it sets a flag on the ViewContext’s ViewData dictionary to indicate that the view is to be rendered as jQuery collection item template. This is then handled by the &lt;em&gt;@Html.BeginCollectionItem&lt;/em&gt; by generating an index template placeholder based .Index hidden field for model binding instead of one with an actual GUID value:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public static IDisposable BeginCollectionItem&amp;lt;TModel&amp;gt;(this HtmlHelper&amp;lt;TModel&amp;gt; html, string collectionName)
{
    string collectionIndexFieldName = String.Format(&quot;{0}.Index&quot;, collectionName);

    string itemIndex = null;
    if (html.ViewData.ContainsKey(JQueryTemplatingEnabledKey)) {
        itemIndex = &quot;${index}&quot;;
    } else {
        itemIndex = GetCollectionItemIndex(collectionIndexFieldName);
    }

    string collectionItemName = String.Format(&quot;{0}[{1}]&quot;, collectionName, itemIndex);

    TagBuilder indexField = new TagBuilder(&quot;input&quot;);
    indexField.MergeAttributes(new Dictionary&amp;lt;string, string&amp;gt;() {
        { &quot;name&quot;, collectionIndexFieldName },
        { &quot;value&quot;, itemIndex },
        { &quot;type&quot;, &quot;hidden&quot; },
        { &quot;autocomplete&quot;, &quot;off&quot; }
    });
// snip---&lt;/pre&gt;

&lt;p&gt;That’s it! We are still reusing our ASP.NET views, model binding and validation, but no longer require an AJAX request to fetch a new editor row!.&lt;/p&gt;

&lt;p&gt;In Part 3 I will look at Knockout JS templating, data binding and moving variable length reorderable collection editing completely on the client side with the MVVM pattern and using JavaScript form serialization and JSON data submission and model binding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next: &lt;a href=&quot;http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/&quot;&gt;Part 3 and Knockout JS client-side collection editing, JSON model binding and client-side validation.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 20 Jun 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Editing Variable Length Reorderable Collections in ASP.NET MVC &amp;#8211; Part 1: ASP.NET MVC Views</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;

&lt;p&gt;I have decided to write a short series of blog posts on editing collections and more specifically variable length collections in ASP.NET MVC. I will take two different implementation approaches:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/&quot;&gt;In &lt;strong&gt;Part 1&lt;/strong&gt;&lt;/a&gt; I look at implementing collection editing by sticking to facilities provided to us by ASP.NET MVC such as views, partial views, editor templates, model binding, model validation, etc.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/&quot;&gt;In &lt;strong&gt;Part 2&lt;/strong&gt;&lt;/a&gt; I further enhance the sample by using jQuery Templates, but still utilize the same ASP.NET MVC views from Part 1.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/&quot;&gt;In &lt;strong&gt;Part 3&lt;/strong&gt;&lt;/a&gt; I will look at Knockout JS templating, data binding and moving variable length reorderable collection editing completely on the client side with the MVVM pattern and JSON data submission and model binding.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The aspects I will consider are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dynamically adding, removing and reordering items to/from the collection&lt;/li&gt;
  &lt;li&gt;Validation implications&lt;/li&gt;
  &lt;li&gt;Code Reusability and Refactoring implications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will assume that you are already familiar with ASP.NET MVC and basic JavaScript concepts.&lt;/p&gt;

&lt;h3 id=&quot;source-code&quot;&gt;Source Code&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/ivanz/ASP.NET-MVC-Collection-Editing&quot; target=&quot;_blank&quot;&gt;All source code is available on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-sample&quot;&gt;The Sample&lt;/h3&gt;

&lt;p&gt;What I am going to build is a little sample where we have a user who has a list of favourite movies. It will look roughly like on the image below and will allow for adding new favourite movies, removing favourite movies and also reordering them up and down using the drag handler.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/image3.png&quot;&gt;&lt;img style=&quot;background-image: none; margin: 10px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;&quot; title=&quot;image&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/image_thumb3.png&quot; border=&quot;0&quot; alt=&quot;image&quot; width=&quot;554&quot; height=&quot;439&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;domain-model&quot;&gt;Domain Model&lt;/h3&gt;

&lt;p&gt;The domain model is basically:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class User
{
    public int? Id { get; set; }
    [Required]
    public string Name { get; set; }
    public IList&amp;lt;Movie&amp;gt; FavouriteMovies { get; set; }
}&lt;/pre&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class Movie
{
    [Required]
    public string Title { get; set; }
    public int Rating { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Let’s get cracking!&lt;/p&gt;

&lt;h3 id=&quot;an-edit-view&quot;&gt;An Edit View&lt;/h3&gt;

&lt;p&gt;Let’s start by creating a first-pass edit view for our Person to look like the one on the image above:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;@model CollectionEditing.Models.User
@{ ViewBag.Title = &quot;Edit My Account&quot;; }

&amp;lt;h2&amp;gt;Edit&amp;lt;/h2&amp;gt;

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    &amp;lt;fieldset&amp;gt;
        &amp;lt;legend&amp;gt;My Details&amp;lt;/legend&amp;gt;

        @Html.HiddenFor(model =&amp;gt; model.Id)

        &amp;lt;div class=&quot;editor-label&quot;&amp;gt;
            @Html.LabelFor(model =&amp;gt; model.Name)
        &amp;lt;/div&amp;gt;
        &amp;lt;div class=&quot;editor-field&quot;&amp;gt;
            @Html.EditorFor(model =&amp;gt; model.Name)
            @Html.ValidationMessageFor(model =&amp;gt; model.Name)
        &amp;lt;/div&amp;gt;
    &amp;lt;/fieldset&amp;gt;
    
    &amp;lt;fieldset&amp;gt;
        &amp;lt;legend&amp;gt;My Favourite Movies&amp;lt;/legend&amp;gt;

        @if (Model.FavouriteMovies == null || Model.FavouriteMovies.Count == 0) {
            &amp;lt;p&amp;gt;None.&amp;lt;/p&amp;gt;
        } else {
            &amp;lt;ul id=&quot;movieEditor&quot; style=&quot;list-style-type: none&quot;&amp;gt;
                @for (int i=0; i &amp;lt; Model.FavouriteMovies.Count; i++) {
                    &amp;lt;li style=&quot;padding-bottom:15px&quot;&amp;gt;
                        &amp;lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&amp;gt;

                        @Html.LabelFor(model =&amp;gt; model.FavouriteMovies[i].Title)
                        @Html.EditorFor(model =&amp;gt; model.FavouriteMovies[i].Title)
                        @Html.ValidationMessageFor(model =&amp;gt; model.FavouriteMovies[i].Title)

                        @Html.LabelFor(model =&amp;gt; model.FavouriteMovies[i].Rating)
                        @Html.EditorFor(model =&amp;gt; model.FavouriteMovies[i].Rating)
                        @Html.ValidationMessageFor(model =&amp;gt; model.FavouriteMovies[i].Rating)

                        &amp;lt;a href=&quot;#&quot; onclick=&quot;$(this).parent().remove();&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;
                    &amp;lt;/li&amp;gt;
                }
            &amp;lt;/ul&amp;gt;
            &amp;lt;a href=&quot;#&quot;&amp;gt;Add another&amp;lt;/a&amp;gt;
        }

        &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
            $(function () {
                $(&quot;#movieEditor&quot;).sortable();
            });
        &amp;lt;/script&amp;gt;
    &amp;lt;/fieldset&amp;gt;
    
    &amp;lt;p&amp;gt;
        &amp;lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&amp;gt;
        &amp;lt;a href=&quot;/&quot;&amp;gt;Cancel&amp;lt;/a&amp;gt;
    &amp;lt;/p&amp;gt;
}&lt;/pre&gt;

&lt;p&gt;The view is creating a list of editing controls for each of the movies in &lt;em&gt;Person.FavouriteMovies&lt;/em&gt;. I am using a jQuery selector and dom function to remove a movie when the user clicks “Delete”  and also a &lt;a href=&quot;http://jqueryui.com/demos/sortable/&quot; target=&quot;_blank&quot;&gt;jQuery UI Sortable&lt;/a&gt; to make the items from the HTML list drag and droppable up and down.&lt;/p&gt;

&lt;p&gt;With this done we immediately face the first problem: &lt;span style=&quot;text-decoration: underline;&quot;&gt;We haven’t implemented the “Add another”&lt;/span&gt;. Before we do that let’s consider how ASP.NET MVC model binding of collections works.&lt;/p&gt;

&lt;h3 id=&quot;aspnet-mvc-collection-model-binding-patterns&quot;&gt;ASP.NET MVC Collection Model Binding Patterns&lt;/h3&gt;

&lt;p&gt;There are two patterns for model binding collections in ASP.NET MVC. The &lt;strong&gt;first one&lt;/strong&gt; you have just seen:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;@for (int i=0; i &amp;lt; Model.FavouriteMovies.Count; i++) {
    @Html.LabelFor(model =&amp;gt; model.FavouriteMovies[i].Title)
    @Html.EditorFor(model =&amp;gt; model.FavouriteMovies[i].Title)
    @Html.ValidationMessageFor(model =&amp;gt; model.FavouriteMovies[i].Title)
…
}&lt;/pre&gt;

&lt;p&gt;which generates similar HTML:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;label for=&quot;FavouriteMovies_0__Title&quot;&amp;gt;Title&amp;lt;/label&amp;gt;
&amp;lt;input id=&quot;FavouriteMovies_0__Title&quot; name=&quot;FavouriteMovies[0].Title&quot; type=&quot;text&quot; value=&quot;&quot; /&amp;gt;
&amp;lt;span class=&quot;field-validation-error&quot;&amp;gt;The Title field is required.&amp;lt;/span&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/p&amp;gt;&lt;/p&gt;

&lt;p&gt;This is really great for displaying collections and editing static length collections, but problematic when we want to edit variable length collections, because:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Indices have to be sequential (0, 1, 2, 3, …). If they aren’t ASP.NET MVC stops at the first gap. E.g. if you have item 0, 1, 3, 4 after the model binding has finished you will end up with a collection of two items only – 1 and 2 instead of four items.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;If you were to reorder the list in the HTML ASP.NET MVC will apply the indices order not the fields order when doing model binding.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This basically means that add/remove/reorder scenarios are no go with this. It’s not impossible but it will be big big mess tracking add/remove/reorder actions and re-indexing all field attributes.&lt;/p&gt;

&lt;p&gt;Now, someone might say – “&lt;em&gt;Hey, why don’t you just implement a non-sequential collection model binder?”&lt;/em&gt; .&lt;/p&gt;

&lt;p&gt;Yes, you can write the code for a non-sequential collection model binder. You will however face two major issues with that however. The first being that the &lt;em&gt;IValueProvider&lt;/em&gt; doesn’t expose a way to iterate through all values in the &lt;em&gt;BindingContext&lt;/em&gt; which you can workaround* &lt;em&gt;by hardcoding the model binder to access the current HttpRequest Form values collection (meaning that if someone decides to submit the form via Json or query parameters your model binder won’t work) or I’ve seen one more insane workaround which checks the *BindingContext&lt;/em&gt; one by one from &lt;em&gt;CollectionName[0]&lt;/em&gt; to &lt;em&gt;CollectionName[Int32.MaxValue]&lt;/em&gt; (that’s &lt;span style=&quot;text-decoration: underline;&quot;&gt;2 billion&lt;/span&gt; iterations!).&lt;/p&gt;

&lt;p&gt;Second major issue is that once you create a sequential collection from the non-sequential indices and items and you have a validation error and you re-render the form view your ModelState will no longer match the data. An item that used to be at index X is now at index X-1 after another item before it was deleted, however the ModelState validation message and state still point to X, because this is what you submitted.&lt;/p&gt;

&lt;p&gt;So, even a custom model binder won’t help.&lt;/p&gt;

&lt;p&gt;Thankfully there is a &lt;strong&gt;second pattern&lt;/strong&gt;, which mostly helps for what we want to achieve (even though I don’t think it was designed to solve exactly this):&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;input type=&quot;hidden&quot; name=&quot;FavouriteMovies.Index&quot; value=&quot;indexA&quot;/&amp;gt;
&amp;lt;input name=&quot;FavouriteMovies[indexA].Title&quot; type=&quot;text&quot; value=&quot;&quot; /&amp;gt;
&amp;lt;input name=&quot;FavouriteMovies[indexA].Rating&quot; type=&quot;text&quot; value=&quot;&quot; /&amp;gt;
&amp;lt;input type=&quot;hidden&quot; name=&quot;FavouriteMovies.Index&quot; value=&quot;indexB&quot;/&amp;gt;
&amp;lt;input name=&quot;FavouriteMovies[indexB].Title&quot; type=&quot;text&quot; value=&quot;&quot; /&amp;gt;
&amp;lt;input name=&quot;FavouriteMovies[indexB].Rating&quot; type=&quot;text&quot; value=&quot;&quot; /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/p&amp;gt;&lt;/p&gt;

&lt;p&gt;Notice how we have introduced an “.Index” hidden field for each collection item. By doing that we tell ASP.NET MVC’s model binding “Hey, don’t look for a standard numeric collection index, but instead look for the custom Index value we have specified and just get me the list of items in a collection when you are done”. How does this help?&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We can specify any index value we want&lt;/li&gt;
  &lt;li&gt;The index doesn’t have to be sequential and items will be put in the collection in the order they are in the HTML when submitted.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bam! That’s solves most, but not all of our problems.&lt;/p&gt;

&lt;h3 id=&quot;the-solution&quot;&gt;The Solution&lt;/h3&gt;

&lt;p&gt;Firstly, ASP.NET MVC doesn’t have HTML helpers to generate the “[something].Index” pattern which is major problem since it means we can’t use validation and custom editors. We can fix that by utilizing some ASP.NET templating fu. What we are going to do is move the Movie editor to a its own partial view (MovieEntryEditor.cshtml):&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;@model CollectionEditing.Models.Movie
           
&amp;lt;li style=&quot;padding-bottom:15px&quot;&amp;gt;
    @using (Html.BeginCollectionItem(&quot;FavouriteMovies&quot;)) {
        &amp;lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&amp;gt;

        @Html.LabelFor(model =&amp;gt; model.Title)
        @Html.EditorFor(model =&amp;gt; model.Title)
        @Html.ValidationMessageFor(model =&amp;gt; model.Title)

        @Html.LabelFor(model =&amp;gt; model.Rating)
        @Html.EditorFor(model =&amp;gt; model.Rating)
        @Html.ValidationMessageFor(model =&amp;gt; model.Rating)

        &amp;lt;a href=&quot;#&quot; onclick=&quot;$(this).parent().remove();&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;
    }
&amp;lt;/li&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;lt;/p&amp;gt;&lt;/p&gt;

&lt;p&gt;And update our Edit view to use it:&lt;/p&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;ul id=&quot;movieEditor&quot; style=&quot;list-style-type: none&quot;&amp;gt;
    @foreach (Movie movie in Model.FavouriteMovies) {
        Html.RenderPartial(&quot;MovieEntryEditor&quot;, movie);
    }
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;a id=&quot;addAnother&quot; href=&quot;#&quot;&amp;gt;Add another&amp;lt;/a&amp;gt;&lt;/pre&gt;

&lt;p&gt;Notice two things – firstly the Movie partial edit view uses standard Html helpers and secondly there is a call to something custom called &lt;em&gt;Html.BeginCollectionItem. *You might even ask yourself: Wait a second. This won’t work, because the partial view will produce names such as “Title” instead of “FavouriteMovies[xxx].Title”, so let me show you the source code of *Html.BeginCollectionItem&lt;/em&gt;:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public static IDisposable BeginCollectionItem&amp;lt;TModel&amp;gt;(this HtmlHelper&amp;lt;TModel&amp;gt; html,                                                       string collectionName)
{
    string itemIndex = Guid.NewGuid().ToString();
    string collectionItemName = String.Format(&quot;{0}[{1}]&quot;, collectionName, itemIndex);

    TagBuilder indexField = new TagBuilder(&quot;input&quot;);
    indexField.MergeAttributes(new Dictionary&amp;lt;string, string&amp;gt;() {
        { &quot;name&quot;, String.Format(&quot;{0}.Index&quot;, collectionName) },
        { &quot;value&quot;, itemIndex },
        { &quot;type&quot;, &quot;hidden&quot; },
        { &quot;autocomplete&quot;, &quot;off&quot; }
    });

    html.ViewContext.Writer.WriteLine(indexField.ToString(TagRenderMode.SelfClosing));
    return new CollectionItemNamePrefixScope(html.ViewData.TemplateInfo, collectionItemName);
}

private class CollectionItemNamePrefixScope : IDisposable
{
    private readonly TemplateInfo _templateInfo;
    private readonly string _previousPrefix;

    public CollectionItemNamePrefixScope(TemplateInfo templateInfo, string collectionItemName)
    {
        this._templateInfo = templateInfo;

        _previousPrefix = templateInfo.HtmlFieldPrefix;
        templateInfo.HtmlFieldPrefix = collectionItemName;
    }

    public void Dispose()
    {
        _templateInfo.HtmlFieldPrefix = _previousPrefix;
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;lt;/p&amp;gt;&lt;/p&gt;

&lt;p&gt;This helper does two things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Appends a hidden Index field to the output with a random GUID value (remember that using the .Index pattern an index can be any string)&lt;/li&gt;
  &lt;li&gt;Scopes the execution of the helper via an &lt;em&gt;IDisposable&lt;/em&gt; and sets the template rendering context (html helperes and display/editor templates) to be “&lt;em&gt;FavouriteMovies[GUID].&lt;/em&gt;”, so we end up with HTML like this:&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;input autocomplete=&quot;off&quot; name=&quot;FavouriteMovies.Index&quot; type=&quot;hidden&quot; value=&quot;6d85a95b-1dee-4175-bfae-73fad6a3763b&quot; /&amp;gt;
&amp;lt;label&amp;gt;Title&amp;lt;/label&amp;gt;
&amp;lt;input class=&quot;text-box single-line&quot; name=&quot;FavouriteMovies[6d85a95b-1dee-4175-bfae-73fad6a3763b].Title&quot; type=&quot;text&quot; value=&quot;Movie 1&quot; /&amp;gt;
&amp;lt;span class=&quot;field-validation-valid&quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;/pre&gt;

&lt;p&gt;This solves the problem of using Html field templates and basically reusing ASP.NET facilities instead of having to write html by hand, but it leads me to the second quirk that we need to address.&lt;/p&gt;

&lt;p&gt;Let me show you the second and final problem. Disable client side validation and delete the title of e.g. “Movie 2” and click submit. Validation will fail, because Title of a movie is a required field, but while we are shown the edit form again** there are no validation messages**:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/image4.png&quot;&gt;&lt;img style=&quot;background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;&quot; title=&quot;image&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/image_thumb4.png&quot; border=&quot;0&quot; alt=&quot;image&quot; width=&quot;544&quot; height=&quot;174&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is that? It’s the same problem I mentioned earlier in this post. Each time we render the view we assign different names to the fields, which do not match the ones submitted and leads to a *ModelState *inconsistency. We have to figure out how to persist the name and more specifically the Index across requests. We have two options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add a hidden CollectionIndex field and CollectionIndex property on the &lt;em&gt;Movie&lt;/em&gt; object to persist the &lt;em&gt;FavouriteMovies.Index&lt;/em&gt;. This however is intrusive and suboptimal.&lt;/li&gt;
  &lt;li&gt;Instead of polluting the &lt;em&gt;Movie&lt;/em&gt; object with an extra property be smart and in our helper &lt;em&gt;Html.BeginCollectionItem&lt;/em&gt; reapply/reuse the submitted &lt;em&gt;FavouriteMovies.Index&lt;/em&gt; form values.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s replace in &lt;em&gt;Html.BeginCollectionItem&lt;/em&gt; this line:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;string itemIndex = Guid.New().ToString();&lt;/pre&gt;

&lt;p&gt;with:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;string itemIndex = GetCollectionItemIndex(collectionIndexFieldName);&lt;/pre&gt;

&lt;p&gt;And here’ is the code for GetCollectionItemIndex:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;private static string GetCollectionItemIndex(string collectionIndexFieldName)
{
    Queue&amp;lt;string&amp;gt; previousIndices = (Queue&amp;lt;string&amp;gt;) HttpContext.Current.Items[collectionIndexFieldName];
    if (previousIndices == null) {
        HttpContext.Current.Items[collectionIndexFieldName] = previousIndices = new Queue&amp;lt;string&amp;gt;();

        string previousIndicesValues = HttpContext.Current.Request[collectionIndexFieldName];
        if (!String.IsNullOrWhiteSpace(previousIndicesValues)) {
            foreach (string index in previousIndicesValues.Split(&apos;,&apos;))
                previousIndices.Enqueue(index);
        }
    }

    return previousIndices.Count &amp;gt; 0 ? previousIndices.Dequeue() : Guid.NewGuid().ToString();
}&lt;/pre&gt;
&lt;p&gt;&amp;lt;/p&amp;gt;&lt;/p&gt;

&lt;p&gt;We get all submitted values for e.g. “&lt;em&gt;FavouriteMovie.Index&lt;/em&gt;” put them in a queue, which we store for the duration of the request. Each time we render a collection item we dequeue its old index value and if none is available we generate a new one. That way we preserve the Index across requests and can have a consistent &lt;em&gt;ModelState&lt;/em&gt; and see validation errors and messages:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/06/image5.png&quot;&gt;&lt;img style=&quot;background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;&quot; title=&quot;image&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/06/image_thumb5.png&quot; border=&quot;0&quot; alt=&quot;image&quot; width=&quot;684&quot; height=&quot;150&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All that is left is to implement the “Add another” button functionality and we can do that easily by appending a new row to the movie editor, which we can fetch using Ajax and use our existing MovieEntryEditor.cshtml partial view like that:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public ActionResult MovieEntryRow()
{
    return PartialView(&quot;MovieEntryEditor&quot;);
}&lt;/pre&gt;

&lt;p&gt;And then add the follwing “Add Another” click handler:&lt;/p&gt;

&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;$(&quot;#addAnother&quot;).click(function () {
    $.get(&apos;/User/MovieEntryRow&apos;, function (template) {
        $(&quot;#movieEditor&quot;).append(template);
    });
});&lt;/pre&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;While not immediately obvious editing variable length reorderable collections with standard ASP.NET MVC is possible and what I like about this approach is that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We can keep using traditional ASP.NET html helpers, editor and display templates (Html.EditorFor, etc.) with in our collection editing&lt;/li&gt;
  &lt;li&gt;We can make use of the ASP.NET MVC model validation client and server side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I don’t like that much however is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;That we have to use an AJAX request to append a new row to the editor.&lt;/li&gt;
  &lt;li&gt;That we need to use the name of the collection in the movie editor partial view, but otherwise when doing the standalone AJAX get request the name context won’t be properly set for the partial template fields.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would love to hear your thoughts. The sample source code is available on my &lt;a href=&quot;http://github.com/ivanz/ASP.NET-MVC-Collection-Editing&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next: &lt;strong&gt;&lt;a href=&quot;http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/&quot;&gt;Part 2 and how to avoid having an AJAX request with the use of jQuery Templates&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Thu, 16 Jun 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Java BDD with JBehave and Watij in Eclipse with JUnit</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;The purpose of this post is to explain how to write BDD acceptance tests in Java using the gherkin syntax, run those with JUnit and implement them using Web Browser automation.&lt;/p&gt;

&lt;p&gt;Before I begin let me assure you that I haven’t left the .NET church for the Java one and while I really don’t enjoy writing in Java and using Eclipse sometimes a man has to do what a man has to do.&lt;/p&gt;

&lt;p&gt;So yeah I spend an afternoon trying to figure out the state of BDD (Behavior Driven Development) tools for Java and it’s pretty poor so far. If you want to write gherkin syntax based behavioral specifications, which are executable inside Eclipse as JUnit tests you are stuck only with &lt;a href=&quot;http://jbehave.org/&quot;&gt;JBehave&lt;/a&gt;. JBehave however is a monster with poor documentation, not so easily discoverable fluent API and little to none third party documentation content on forums and sites. BTW don’t get fooled like me – insetad of getting the core package you want to get the Web package because the latter has all the .jar dependencies bundled unlike the first one. Enough bashing, lets get down to business.&lt;/p&gt;

&lt;p&gt;Let’s say we have the following “Search” story and a more specific scenario – “display an error dialog if I don’t fill in the search form”:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Narrative: I should be able to search

Scenario: I should see an error if I try to search without filling in the search form fields.

When I open &apos;http://mysite.com&apos;
When I click on the &apos;Search&apos; button
Then I should see an error
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First thing you will notice is that JBehave doesn’t support the “And” keyword so we can’t wring “When I open … AND I click on the Seach button”.&lt;/p&gt;

&lt;p&gt;Similar to other gherkin/cucumber based frameworks JBehave allows us to implement each step of the scenario as a method in a class, which optionally takes parameters mapped to words from the scenario. The above one can be stubbed like bellow. Also not that if properly configured you can make JBehave junit runner spit out the stubs for you to copy paste in your code (more about that later):&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Search&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@When&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I open &apos;$page&apos;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;whenIOpen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// TODO&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@When&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I click on the &apos;$buttonText&apos; button&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;whenIClickOnTheButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buttonText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// TODO&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Then&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I should see an error&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;thenIShouldSeeAnError&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(){&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// TODO&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To implement the browser automation in Java there exist a Java variant of the Ruby watir library (and the .NET Watin library) called … surprise… watiJ. It’s available &lt;a href=&quot;http://watij.com/&quot;&gt;here&lt;/a&gt;. Major pitfall with it though is that it actually embeds the IE COM component and mozilla’s ghecko engine instead launching the real IE/Firefox (like the above mentioned framework do) and it only supports IE6 and I saw some C++ runtime problems with the ghecko engine. Nevertheless to give you a feel of how the above tests can be implemented:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Search&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StoryBase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@When&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I open &apos;$page&apos;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;whenIOpen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;WebBrowser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pauseUntilReady&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@When&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I click on the &apos;$buttonText&apos; button&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;whenIClickOnTheButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buttonText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Tag&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebBrowser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;search&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;assertNotNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pauseUntilReady&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Then&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I should see an error&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;thenIShouldSeeAnError&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(){&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Tag&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorDialogTitleDiv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebBrowser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dijitDialogTitle&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;assertNotNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorDialogTitleDiv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorDialogTitleDiv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;innerHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, how about running them? A few things before that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;JBehave expects you to save stories as .story files in your source code tree&lt;/li&gt;
  &lt;li&gt;JBehave expects you to implement and configure problematically a *JUnitStory *for each story, so that it’s runnable through JUnit.&lt;/li&gt;
  &lt;li&gt;It will take your JUnitStory subclass implementation – for example “&lt;em&gt;HelloWorldStory extends JUnitStory” *and look for the plain text file &lt;/em&gt;hello_world_story.story*&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To save myself from having to configure each story  I present you my *StoryBase *base class, which:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Initializes WatiJ and exposes it to subclasses&lt;/li&gt;
  &lt;li&gt;Configures JBehave to look for the .story files in the same directory as the class.&lt;/li&gt;
  &lt;li&gt;Configures JBehave/JUnit to look for the steps test methods of a story scenario in the subclass.&lt;/li&gt;
  &lt;li&gt;Configures JBehave to print out detailed information in the Console whilst running (such as the method stubs if any are missing)&lt;/li&gt;
  &lt;li&gt;Configures JBehave to spit out HTML report in &lt;em&gt;myproject/target/jbehave-report/&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here it is:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StoryBase&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JUnitStory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebSpec&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebBrowser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebSpec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ie&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Configuration&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MostUsefulConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;useStoryLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoadFromClasspath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClassLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()))&lt;/span&gt;
    	    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;useStoryReporterBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    	    		&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StoryReporterBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    	    			&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withDefaultFormats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    	    			&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withFormats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CONSOLE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    	    			&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withRelativeDirectory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;jbehave-report&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;candidateSteps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InstanceStepsFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createCandidateSteps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then all that’s left is to make the Search class extend the StoryBase class and it is now runnable in JUnit inside and outside Eclipse.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Search&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StoryBase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/Untitled.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-764&quot; title=&quot;Project Tree&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/Untitled.png&quot; alt=&quot;&quot; width=&quot;178&quot; height=&quot;108&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/junit.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-763&quot; title=&quot;junit&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/junit.png&quot; alt=&quot;&quot; width=&quot;649&quot; height=&quot;85&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

</description>
                
                            <pubDate>Wed, 25 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/25/java-bdd-with-jbehave-and-watij-in-eclipse-with-junit/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/25/java-bdd-with-jbehave-and-watij-in-eclipse-with-junit/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Triply: Day 11 Summary</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;11 days ago I &lt;a href=&quot;http://ivanz.com/2011/05/02/introducing-triply-for-foursquare/&quot; title=&quot;Introducing Triply for Foursquare&quot;&gt;posted the launch notice&lt;/a&gt; for &lt;a href=&quot;http://triply.net&quot;&gt;Triply&lt;/a&gt;. The only other place where I publicized it was on the Foursquare Apps list &lt;a href=&quot;https://foursquare.com/app/triply&quot;&gt;here&lt;/a&gt;. It was very surprising for me that given no “advertisement”, no web design and very little features it managed for 11 days to score:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;103 user accounts – 83 Foursquare and 22 Facebook&lt;/li&gt;
  &lt;li&gt;2226 actions performed around the site&lt;/li&gt;
  &lt;li&gt;651 visits&lt;/li&gt;
  &lt;li&gt;432 visitors&lt;/li&gt;
  &lt;li&gt;10 Twitter followers&lt;/li&gt;
  &lt;li&gt;14 Facebook page fans&lt;/li&gt;
  &lt;li&gt;2 Feature requests in UserVoice (completed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used real time analytics (&lt;a href=&quot;http://woopra.com&quot;&gt;Woopra&lt;/a&gt;) to monitor the users navigation flow (not that there are many pages to navigate around) and that helped me to optimize the experience, especially in terms of login flow. For example instead of asking the user to sign in with Foursquare or Facebook to share a trip I redesigned it to show the actual page and only prompt for login when the user needs to import Checkins. As they say a picture is worth a thousand words, but the actual thing is priceless.&lt;/p&gt;

&lt;p&gt;Other new features since launch are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Facebook Places Checkins support&lt;/li&gt;
  &lt;li&gt;Browse trips interface where a user can browser trips, days out and experiences by City, Country and latest&lt;/li&gt;
  &lt;li&gt;Allow trips to be downloaded as a .GPX file which users can open with Google Earth and Garmin sat navs. Adding support for other geo formats for other satnavs won’t be hard either.&lt;/li&gt;
  &lt;li&gt;A lot of polish and fixes in the backend. Thanks god for &lt;a href=&quot;http://code.google.com/p/elmah/&quot;&gt;ELMAH&lt;/a&gt;, which helped me log all problems around the site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What’s next?&lt;/p&gt;

&lt;p&gt;I am on a cross road at the moment as I need:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A web design (well overdue)&lt;/li&gt;
  &lt;li&gt;Someone to bounce ideas off and vice-versa (co-founder?) in which direction to take Triply as I think there are many directions Triply can go. For example I can make it the bit.ly for sharing trips/days out, etc or I can make it a trip diary type of thing by pulling and displaying photos of the trip from Flickr (using EXIF location data and search), etc. All fun ideas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But how do both of those fit together? Doesn’t the design depend on the future features and vice-versa?&lt;/p&gt;

</description>
                
                            <pubDate>Thu, 12 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/12/triply-day-11-summary/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/12/triply-day-11-summary/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Client-Side XSLT Transformations with JavaScript</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I bet you haven’t ever thought of doing XSLT transformations inside the Web Browser on the client-side, but anyway it’s absolutely possible (cross-browser) and it performs pretty well as well, which shouldn’t be a big surprise since the browser is optimized to work with markup.&lt;/p&gt;

&lt;p&gt;Real-life practical applications of this however I haven’t thought of yet, but possibly:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Use XSLT to consume old XML-based web services and convert the XML into JSON on the client side on the fly. Come on, I know you want to! Why do it properly when you can do it in JavaScript?&lt;/li&gt;
  &lt;li&gt;Create a JavaScript-only  CMS that loads Word documents directly and uses XSLT to display HTML (.docx is zipped xml). Again, why do it properly when you can do it in JavaScript?&lt;/li&gt;
  &lt;li&gt;For fun and zero profit!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the XSLT transformer JavaScript class and sample. The class uses the Dojo JavaScript framework, but only for the browser checks and AJAX requests, so you can easily replace those with JQuery if you wish. Take it under the MIT/X11 license. There is also a &lt;a href=&quot;http://ivanz.com/files/demos/js-xslt/demo.html&quot;&gt;useless demo here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sample&lt;/em&gt;:&lt;/p&gt;

&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;// to transform
var xslTransform = new XslTransform(&quot;/path/to/sample.xsl&quot;);
var outputText = xslTransform.transform(&quot;/path/to/sample.xml&quot;);
&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;XslTransform.js&lt;/em&gt;:&lt;/p&gt;

&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;dojo.provide(&quot;XslTransform&quot;);

dojo.declare(&quot;XslTransform&quot;, [],
{
	_xslDoc : null,
	_xslPath : null,

	constructor : function(xslPath) {
		this._xslPath = xslPath;
	},

	transform : function(xmlPath) {
		if (this._xslDoc === null)
			this._xslDoc = this._loadXML(this._xslPath);

		var result = null;
		var xmlDoc = this._loadXML(xmlPath);

		if (dojo.isIE) {
			result = xmlDoc.transformNode(this._xslDoc);
		} else if(typeof XSLTProcessor !== undefined) {
			xsltProcessor = new XSLTProcessor();
	  		xsltProcessor.importStylesheet(this._xslDoc);

	  		var ownerDocument = document.implementation.createDocument(&quot;&quot;, &quot;&quot;, null);
	  		result = xsltProcessor.transformToFragment(xmlDoc, ownerDocument);
		} else {
			alert(&quot;Your browser doesn&apos;t support XSLT!&quot;);
		}

		return result;

	},

	createXMLDocument : function(xmlText) {
		var xmlDoc = null;

		if (dojo.isIE) {
			xmlDoc = new ActiveXObject(&quot;Microsoft.XMLDOM&quot;);
			xmlDoc.async = false;
			xmlDoc.loadXML(xmlText);
		} else if (window.DOMParser) {
			parser = new DOMParser();
			xmlDoc = parser.parseFromString(xmlText, &quot;text/xml&quot;);
		} else {
			alert(&quot;Your browser doesn&apos;t suppoprt XML parsing!&quot;);
		}

		return xmlDoc;
	},

	// Synchronously loads a remote xml file
	_loadXML : function(xmlPath) {
		var getResult = dojo.xhrGet({
			url : xmlPath,
			handleAs : &quot;xml&quot;,
			sync: true
		});

		var xml = null;
		// Returns immediately, because the GET is synchronous.
		var xmlData = getResult.then(function (response) {
			xml = response;
		});

		return xml;
	}
});

&lt;/pre&gt;

</description>
                
                            <pubDate>Thu, 12 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/12/client-side-xslt-transformations-with-javascript/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/12/client-side-xslt-transformations-with-javascript/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Logging JavaScript Errors with ELMAH in ASP.NET MVC</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;One final piece of information I wanted to add to &lt;a href=&quot;http://ivanz.com/2011/05/08/asp-net-mvc-magical-error-logging-with-elmah/&quot; title=&quot;ASP.NET MVC Magical Error Logging with ELMAH&quot;&gt;my last blog post about setting up ELMAH for ASP.NET MVC&lt;/a&gt; is how to log Client Side/JavaScript errors with &lt;a href=&quot;http://code.google.com/p/elmah/&quot;&gt;ELMAH&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To do that we need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Because ELMAH works with exceptions we will need to define a *JavaScriptErrorException *to represent our client side errors in the logs:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;using System;

namespace Triply.Extensions
{
	[Serializable]
	public class JavaScriptErrorException : Exception
	{
		public JavaScriptErrorException (string message) : base(message)
		{
		}
	}
}&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;Define a Controller Action to be invoked by the client side that takes in an error message:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;using System;
using System.Web.Mvc;
using Elmah;
using Triply.Extensions;

namespace Triply.Controllers
{
	public class HomeController : Controller
	{
		[HttpPost]
		public void LogJavaScriptError(string message)
		{
			ErrorSignal.FromCurrentContext().Raise(new JavaScriptErrorException(message));
		}
	}
}&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;Use an AJAX post with a message to log the error&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;function logError(details) {
    $.post(&quot;/Home/LogJavaScriptError&quot;, { message: details });
}
&lt;/pre&gt;

&lt;p&gt;Done!&lt;/p&gt;

</description>
                
                            <pubDate>Sun, 08 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/08/logging-javascript-errors-with-elmah/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/08/logging-javascript-errors-with-elmah/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>ASP.NET MVC Magical Error Logging with ELMAH</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;If you aren’t using ELMAH (Error Logging Modules and Handlers) you should be – &lt;a href=&quot;http://code.google.com/p/elmah/&quot;&gt;http://code.google.com/p/elmah/&lt;/a&gt; It’s the best thing since sliced bread for logging ASP.NET errors with practically zero effort. It basically plugs into the ASP.NET pipeline and logs all unhandled exceptions thrown and HTTP error codes together with all sorts of other useful information such as request url, stacktrace, current user username, cookies and more. You can say it makes a snapshot of the Yellow Screen of Death with extra information. It then gives you a simple web access to the recent errors logged (by default at http//mysite.com/elmah.axd), exposing a RSS feed as well. It’s fully configurable (error filters, multiple backend log storage systems support, etc) and also can be set up to send emails on error.&lt;/p&gt;

&lt;p&gt;Some screenshots:&lt;/p&gt;

&lt;div style=&quot;width: 310px&quot; class=&quot;wp-caption aligncenter&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/elmah-log-1.png&quot;&gt;&lt;img title=&quot;elmah-log-1&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/elmah-log-1-300x43.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;43&quot; /&gt;&lt;/a&gt;
  
  &lt;p class=&quot;wp-caption-text&quot;&gt;
    List of Errors using the Web Interface
  &lt;/p&gt;
&lt;/div&gt;

&lt;div style=&quot;width: 310px&quot; class=&quot;wp-caption aligncenter&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/elmah-log-2.png&quot;&gt;&lt;img title=&quot;elmah-log-2&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/elmah-log-2-300x186.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;186&quot; /&gt;&lt;/a&gt;
  
  &lt;p class=&quot;wp-caption-text&quot;&gt;
    Error Details in the web interface
  &lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/elmah-log-1.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can pull ELMAH through nuget via the “Elmah” package., which will download it and add a reference. The steps to get it all set up for ASP.NET MVC are as follows.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Register Elmah configuration sections in the &lt;em&gt;Web.config&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;sectionGroup name=&quot;elmah&quot;&amp;gt;
      &amp;lt;section name=&quot;security&quot; requirePermission=&quot;false&quot; type=&quot;Elmah.SecuritySectionHandler, Elmah&quot; /&amp;gt;
      &amp;lt;section name=&quot;errorLog&quot; requirePermission=&quot;false&quot; type=&quot;Elmah.ErrorLogSectionHandler, Elmah&quot; /&amp;gt;
      &amp;lt;section name=&quot;errorMail&quot; requirePermission=&quot;false&quot; type=&quot;Elmah.ErrorMailSectionHandler, Elmah&quot; /&amp;gt;
      &amp;lt;section name=&quot;errorFilter&quot; requirePermission=&quot;false&quot; type=&quot;Elmah.ErrorFilterSectionHandler, Elmah&quot; /&amp;gt;
    &amp;lt;/sectionGroup&amp;gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;Add the root level ELMAH section in &lt;em&gt;Web.config&lt;/em&gt; to tell it where to store the logs and how. Easiest to set up is to have a directory where it stores xml file for each error, &lt;strong&gt;but make sure the IIS process/AppPool has write access to that directory!&lt;/strong&gt; Also I have added a filter to ignore all HTTP 404 errors. Note that this filter won’t work for ASP.NET MVC and I will come back to that later.&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;elmah&amp;gt;
    &amp;lt;security allowRemoteAccess=&quot;1&quot; /&amp;gt;
    &amp;lt;errorLog type=&quot;Elmah.XmlFileErrorLog, Elmah&quot; logPath=&quot;~/App_Data/ElmahLogs&quot; /&amp;gt;
    &amp;lt;errorFilter&amp;gt;
      &amp;lt;test&amp;gt;
        &amp;lt;equal binding=&quot;HttpStatusCode&quot; value=&quot;404&quot; type=&quot;Int32&quot; /&amp;gt;
      &amp;lt;/test&amp;gt;
    &amp;lt;/errorFilter&amp;gt;
  &amp;lt;/elmah&amp;gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;Register ELMAH with the ASP.NET pipeline &lt;strong&gt;both&lt;/strong&gt; in the &lt;strong&gt;system.web **section (when running locally) and the  &lt;/strong&gt;system.webServer** section when deployed to IIS. Just copy paste the below snippet in both sections. Notice how the default configuration says that ELMAH will be available at mysite.com/elmah.axd . You can change that if you want (in both places!)&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;httpModules&amp;gt;
      &amp;lt;add name=&quot;ErrorLog&quot; type=&quot;Elmah.ErrorLogModule, Elmah&quot; /&amp;gt;
    &amp;lt;/httpModules&amp;gt;
    &amp;lt;httpHandlers&amp;gt;
      &amp;lt;add verb=&quot;POST,GET,HEAD&quot; path=&quot;elmah.axd&quot; type=&quot;Elmah.ErrorLogPageFactory, Elmah&quot; /&amp;gt;
    &amp;lt;/httpHandlers&amp;gt;&lt;/pre&gt;

&lt;p&gt;You are done and elmah will be available at http://mysite.com/elmah.axd , but it won’t work quite right with ASP.NET MVC, because of the way errors are handled there, so there are those additional things that need to be set up:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Log exceptions before ASP.NET MVC swallows them if using customErrors or some other code handles and swallows the error. To do this I’ve implemented the below exception filter that logs all handled exceptions. It’s a good example also of how to programatically log errors with ELMAH:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;using System;
using System.Web.Mvc;
using Elmah;

namespace Triply.Extensions
{
	public class ElmahHandledErrorLoggerFilter : IExceptionFilter
	{
		public void OnException (ExceptionContext context)
		{
			// Long only handled exceptions, because all other will be caught by ELMAH anyway.
			if (context.ExceptionHandled)
				ErrorSignal.FromCurrentContext().Raise(context.Exception);
		}
	}
}&lt;/pre&gt;

&lt;p&gt;To register it add it in &lt;em&gt;Global.asax.cs&lt;/em&gt;. The ordering is important – &lt;strong&gt;add it before the HandleErrorAttribute is registered&lt;/strong&gt;.&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public static void RegisterGlobalFilters (GlobalFilterCollection filters)
{
	filters.Add(new ElmahHandledErrorLoggerFilter());
	filters.Add(new HandleErrorAttribute());
}&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;One final note regarding filtering out HTTP 404 errors. In ASP.NET MVC they are raised as exceptions so if you want to ignore them unfortunately you can’t do that declaratively in the Web.config. Instead you have to add the following elmah hooks to your &lt;em&gt;Global.asax.cs&lt;/em&gt; to do it programatically:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;// ELMAH Filtering
		protected void ErrorLog_Filtering (object sender, ExceptionFilterEventArgs e)
		{
			FilterError404(e);
		}

		protected void ErrorMail_Filtering (object sender, ExceptionFilterEventArgs e)
		{
			FilterError404(e);
		}

		// Dismiss 404 errors for ELMAH
		private void FilterError404 (ExceptionFilterEventArgs e)
		{
			if (e.Exception.GetBaseException() is HttpException) {
				HttpException ex = (HttpException)e.Exception.GetBaseException();
				if (ex.GetHttpCode() == 404)
					e.Dismiss();
			}
		}&lt;/pre&gt;

&lt;p&gt;That’s it. Now you get super cool logging (and remember – RSS feed!)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/elmah-log-1.png&quot;&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Sun, 08 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/08/asp-net-mvc-magical-error-logging-with-elmah/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/08/asp-net-mvc-magical-error-logging-with-elmah/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Triply now supports Facebook Places Checkins</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I’ve just published online the support for Facebook Places Checkins in &lt;a href=&quot;http://triply.net&quot;&gt;Triply&lt;/a&gt; . This means that now you can log in and work with checkins either from Foursquare or Facebook Places.&lt;/p&gt;

&lt;p&gt;What &lt;a href=&quot;http://Triply.net&quot;&gt;Triply &lt;/a&gt;really needs now is a good first pass web design, but I am not a web designer and don’t have cash to spend on web design right now, so I wonder what to do &lt;img src=&quot;http://ivanz.com/wp-includes/images/smilies/frownie.png&quot; alt=&quot;:(&quot; class=&quot;wp-smiley&quot; style=&quot;height: 1em; max-height: 1em;&quot; /&gt; . After that I hope I can engage some people for feedback and bounce ideas off to see where we can go from here.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-powered-by.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-746&quot; title=&quot;triply-powered-by&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-powered-by.png&quot; alt=&quot;&quot; width=&quot;503&quot; height=&quot;60&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-dual-login.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-747&quot; title=&quot;triply-dual-login&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-dual-login.png&quot; alt=&quot;&quot; width=&quot;353&quot; height=&quot;187&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-facebook-and-foursquare.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-745&quot; title=&quot;triply-facebook-and-foursquare&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-facebook-and-foursquare.png&quot; alt=&quot;&quot; width=&quot;531&quot; height=&quot;350&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Wed, 04 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/04/triply-now-supports-facebook-places-checkins/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/04/triply-now-supports-facebook-places-checkins/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Introducing Triply for Foursquare</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;During my trip to &lt;a href=&quot;http://en.wikipedia.org/wiki/Dubrovnik&quot;&gt;Dubrovnik &lt;/a&gt;last week whilst checking in on Foursquare an idea struck me – can’t I use the Foursquare checkin history and checkin comments to document the places I visit and also my route. This is how &lt;a href=&quot;http://triply.net&quot;&gt;Triply&lt;/a&gt; was born after a two day hackathon.&lt;/p&gt;

&lt;p&gt;In a single sentence &lt;a href=&quot;http://triply.net&quot;&gt;Triply&lt;/a&gt; lets you &lt;strong&gt;quickly create and share your trips, experiences and days out&lt;/strong&gt; in &lt;strong&gt;three simple steps&lt;/strong&gt; using your &lt;strong&gt;existing Foursquare checkins&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You pick a name and description for the trip/day out/experience:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-1.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-738&quot; title=&quot;about-triply-screenshot-1&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-1.png&quot; alt=&quot;&quot; width=&quot;423&quot; height=&quot;196&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You then pick start/end dates to load the Foursquare Checkins&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-2.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-739&quot; title=&quot;about-triply-screenshot-2&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-2.png&quot; alt=&quot;&quot; width=&quot;547&quot; height=&quot;344&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You then organize (reorder and remove) the checkins and that’s it!&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-3.png&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-3.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-740&quot; title=&quot;about-triply-screenshot-3&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-3.png&quot; alt=&quot;&quot; width=&quot;692&quot; height=&quot;314&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p style=&quot;text-align: left;&quot;&gt;
  Notice the funky AJAX drag and drop goodness:
&lt;/p&gt;

&lt;p style=&quot;text-align: left;&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-4.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-741&quot; title=&quot;about-triply-screenshot-4&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/about-triply-screenshot-4.png&quot; alt=&quot;&quot; width=&quot;413&quot; height=&quot;330&quot; /&gt;&lt;/a&gt;Once saved you get a trip page like the one below, where others can see the route, places and your comments and ask questions, etc.
&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-sample-trip.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-742&quot; title=&quot;triply-sample-trip&quot; src=&quot;http://ivanz.com/wp-content/uploads/2011/05/triply-sample-trip.png&quot; alt=&quot;&quot; width=&quot;728&quot; height=&quot;668&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &amp;nbsp;
&lt;/p&gt;

&lt;p style=&quot;text-align: left;&quot;&gt;
  Triply is ASP.NET MVC 3 and Entity Framework with an SQL Express server at the backend right now. It&amp;#8217;s basically version 0.1 &amp;#8220;Get it out there&amp;#8221; release without even a proper web design, because I am intrigued to hear what people think about the idea.
&lt;/p&gt;

&lt;p style=&quot;text-align: left;&quot;&gt;
  I have personally have many things in mind that can be added in the future such as:
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A Web design, yo know.&lt;/li&gt;
  &lt;li&gt;Have an indicator of the type of place was visited (museum, gallery, beach, etc)&lt;/li&gt;
  &lt;li&gt;Allow to get info about a place quickly such as wikipedia entry for historical places and hotel rating/reviews for hotels.&lt;/li&gt;
  &lt;li&gt;Facebook Places/Checkins support&lt;/li&gt;
  &lt;li&gt;Maybe go down the “trip diary” route as well with auto-mapped/auto-linked photos to places and mobile apps.&lt;/li&gt;
  &lt;li&gt;Maybe go down the “share a fun experience to do” route (e.g. go to this pub, then to this museum, then to that other fun place to spend a great day).&lt;/li&gt;
  &lt;li&gt;and more – basically I feel like this has potential.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;… but it’s just me, so if someone is enthusiastic about the idea and is familiar with the Microsoft technology stack I would be more than happy to team up. You never know some day we might be able to afford to buy the .com or even .ly domain &lt;img src=&quot;http://ivanz.com/wp-includes/images/smilies/simple-smile.png&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; style=&quot;height: 1em; max-height: 1em;&quot; /&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 02 May 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/05/02/introducing-triply-for-foursquare/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/05/02/introducing-triply-for-foursquare/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Storing Date and Time in UTC and the definition &amp;#8220;Today&amp;#8221;</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Storing date and times in UTC on the server side is all nice and dandy, however there are a few gotchas, one of which the definition of “Today” when you a dealing with time zones.&lt;/p&gt;

&lt;p&gt;Say we are dealing with a system where a user can keep a history/log of all the food that he eats along with the date and time of when that happened. Current system times are:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Current User Time (UTC+2): 4 April 01:45&lt;br /&gt;
Current Server time (UTC): 3 April 23:45&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and we have two log entries:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Log Entry User local time (UTC+2): 3 April 19:30&lt;br /&gt;
Log Entry Server UTC time: 3 April 17:30&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Log Entry User local time (UTC+2): 4 April 01:30&lt;br /&gt;
Log Entry Server UTC time: 3 April 23:30&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If a user wants to see all the log entries for “Today” his perspective for today is 4 April, but if we use the current UTC date on the server (3 April) to do the query we are going to end up with two results, but only one of them (the second) is for the 4 April. This makes perfect sense on the server side, because from the server end perspective both of those log entries were logged on the 3rd, but that’s not the case with the user.&lt;/p&gt;

&lt;p&gt;To solve this we need to calculate the start of user today day and end of user today day and use it as a range to query the log history.&lt;/p&gt;

&lt;p&gt;The steps are more or less:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Get the current server time and convert it to user time.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;“Rewind” that user time back to midnight (00:00)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Convert that to back UTC and you get the start of day for the user in server terms.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Add 23 hours, 59 minutes, 59 seconds to the above and you have the end of user day in server terms&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Query for user_start_of_day &amp;lt;= logentry.Date &amp;lt;= user_end_of_day&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A worked example for the above dates and times:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Current Server time (UTC): 3 April 23:45&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Server time UtcNow is 3 April 23:45 and the user is in UTC+2, so the user local time is 4 April 01:45&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;This gives start of day for the user local time at 4 April 00:00&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Which is 3 April 22:00 in server UTC time – the user_start_of_day&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;ul&gt;
      &lt;li&gt;23:59:59 gives us 4 April 21:59:59 as the end of day&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;We query for log entries where the log UTC timestamp is between 3 April 22:00 and 4 April 21:59:59 , which will return only one result in the above case, which is correct.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is also a C# TimeZone class I have for each of my users in one of my toy projects:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class TimeZone : Entity
{
    protected TimeZone ()
    {
    }

    public TimeZone (string name, TimeZoneInfo timeZone)
    {
        if (timeZone == null)
            throw new ArgumentNullException (&quot;timeZone&quot;, &quot;timeZone is null.&quot;);
        if (String.IsNullOrEmpty (name))
            throw new ArgumentException (&quot;name is null or empty.&quot;, &quot;name&quot;);

        Name = name;
        this.TimeZoneInfo = timeZone;
    }

    public virtual string Name { get; set; }
    public virtual TimeZoneInfo TimeZoneInfo { get; set; }

    public virtual DateTime StartOfToday {
        get {
            DateTime serverNow = DateTime.UtcNow;
            DateTime userNow = ToLocalTime(serverNow);
            return ToUniversalTime (userNow.Date);
        }
    }

    public virtual DateTime EndOfToday {
        get { return StartOfToday.Add (new TimeSpan (23, 59, 59)); }
    }

    public virtual DateTime ToLocalTime (DateTime utcTime)
    {
        return TimeZoneInfo.ConvertTimeFromUtc (utcTime, this.TimeZoneInfo);
    }

    public virtual DateTime ToUniversalTime (DateTime localTime)
    {
        if (localTime.Kind == DateTimeKind.Utc)
            return localTime;

        return TimeZoneInfo.ConvertTimeToUtc (localTime, this.TimeZoneInfo);
    }
}&lt;/pre&gt;

&lt;p&gt;P.S: Some of you will spot a further implication of this and that is that we must always store the time as well as the date.&lt;/p&gt;
</description>
                
                            <pubDate>Mon, 04 Apr 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/04/04/storing-date-and-time-in-utc-and-the-definition-today/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/04/04/storing-date-and-time-in-utc-and-the-definition-today/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>PicasaUploader 0.5.4 released</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I have just released a new version of my &lt;a href=&quot;http://ivanz.com/projects/picasauploader/&quot;&gt;PicasaWeb Uploader&lt;/a&gt; tool. This is a maintenance release to fix issues with large video uploads and to port to the new GData API.&lt;/p&gt;

</description>
                
                            <pubDate>Mon, 07 Feb 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/02/07/picasauploader-0-5-4-released/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/02/07/picasauploader-0-5-4-released/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Eclipse Colour Theme Extractor Tool</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I have published my little tool that extracts just the Eclipse colour theme preferences out of the Eclipse exported preferences &lt;a href=&quot;http://ivanz.com/projects/useful-scripts/&quot;&gt;here&lt;/a&gt;. Usage is pretty simple – point it to an Eclipse preferences file and it will spit out the theme, which you can the import into your workspace without importing any other settings.&lt;/p&gt;

</description>
                
                            <pubDate>Sun, 23 Jan 2011 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2011/01/23/eclipse-colour-theme-extractor-tool/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2011/01/23/eclipse-colour-theme-extractor-tool/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Custom model binding using IModelBinder in ASP.NET MVC &amp;#8211; two gotchas</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;There are a few blog posts around the web regarding ASP.NET MVC custom model binding, but there are two key pieces of information missing.&lt;/p&gt;

&lt;p&gt;Just a quick intro – to implement custom model binding in ASP.NET MVC we need to implement the IModelBinder interface:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public interface IModelBinder
{
    object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);
}
&lt;/pre&gt;

&lt;p&gt;For the sake of the example let’s say we have a class (below) that doesn’t have a public constructor and for one or another reason we don’t want to have a view model.&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class Quantity
{
    public Quantity (float value, MeasurementUnits units)
    {
          this.Value = value;
          this.Units = units;
    }

    public float Value { get; set; }
    public MeasurementUnits Units { get; set; }
}

public enum MeasurementUnits  { mg, g, kg, l, kcal }
&lt;/pre&gt;

&lt;p&gt;With this class in ASP.NET MVC the model binding won’t work, because it doesn’t expose a public constructor. We have three options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;“Mirror” the Quantity class in a View Model class, but that also requires mirroring each class that has a property of type *Quantity * as well&lt;/li&gt;
  &lt;li&gt;Manually build an instance by retrieving the units and value from the Request parameters. However this will have to be done in each controller action (code duplication is bad).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use custom model binding.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the model binder:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class QuantityModelBinder : IModelBinder
{
    public object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (controllerContext == null)
            throw new ArgumentNullException (&quot;controllerContext&quot;, &quot;controllerContext is null.&quot;);
        if (bindingContext == null)
            throw new ArgumentNullException (&quot;bindingContext&quot;, &quot;bindingContext is null.&quot;);

        MeasurementUnits? units = TryGet&amp;lt;MeasurementUnits&amp;gt; (bindingContext, &quot;Units&quot;);
        float? value = TryGet&amp;lt;float&amp;gt; (bindingContext, &quot;Value&quot;);

        if (units.HasValue &amp;amp;&amp;amp; value.HasValue)
            return new Quantity (value.Value, units.Value);

        return null;
    }

    private Nullable&amp;lt;T&amp;gt; TryGet&amp;lt;T&amp;gt; (ModelBindingContext bindingContext, string key) where T : struct
    {
        if (String.IsNullOrEmpty (key))
            return null;

        ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + &quot;.&quot; + key);
        if (valueResult == null &amp;amp;&amp;amp; bindingContext.FallbackToEmptyPrefix == true)
            valueResult = bindingContext.ValueProvider.GetValue (key);

        bindingContext.ModelState.SetModelValue (bindingContext.ModelName, valueResult);

        if (valueResult == null)
            return null;

        try {
            return (Nullable&amp;lt;T&amp;gt;)valueResult.ConvertTo (typeof (T));
        } catch (Exception ex) {
            bindingContext.ModelState.AddModelError (bindingContext.ModelName, ex);
            return null;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;The two important gotchas are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If your binding validation fails you should log an appropriate validation error via *ModelState.AddModelError . *It is useful to know that if you add exceptions of type FormatException to the model errors, ASP.NET MVC is smart enough to automatically convert them to string errors post-binding but before it returns control to your controller action.&lt;/li&gt;
  &lt;li&gt;If  you log an error you &lt;em&gt;*must **call *ModelState.SetModelValue&lt;/em&gt; or otherwise if you return null it will cause a &lt;em&gt;NullReferenceException&lt;/em&gt; in the default ASP.NET MVC binder. This is so because unless you call that method the rest of the ASP.NET MVC code (as well as your own code) won’t be able to access &lt;em&gt;ModelState[propertyName]&lt;/em&gt; and because it doesn’t handle that it blows up.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;P.S:  If I have to be pedantic and the code path is not critical I won’t use strings in the model binder to refer to the Quantity properties. Instead I would use something like what I’ve written about in will use the method described in &lt;a href=&quot;http://ivanz.com/2009/12/04/how-to-avoid-passing-property-names-as-strings-using-c-3-0-expression-trees/&quot;&gt;How to avoid passing property names as strings using C# 3.0 Expression Trees&lt;/a&gt; .&lt;/p&gt;

</description>
                
                            <pubDate>Wed, 03 Nov 2010 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>How to import a database schema into SQL Server Express with Visual Studio</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Today I needed to import my SQL Server schema into a SQL Server Express instance on a different machine. I only have Visual Studio on this machine and no SQL Server Management Studio installed, so it took me a bit to figure out how to import the schema, so here it goes.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add the SQL Server Express instance to the Server Explorer. It’s located at “.\SQLEXPRESS”.&lt;/li&gt;
  &lt;li&gt;Open the T-SQL database schema. It will say “not connected” at the end of the tab caption.&lt;/li&gt;
  &lt;li&gt;In the “Data” menu you will have to “Connect” and then Validate and Execute SQL.&lt;/li&gt;
  &lt;li&gt;Done.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;http://ivanz.com/wp-content/uploads/2010/09/connect.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-724&quot; title=&quot;connect&quot; src=&quot;http://ivanz.com/wp-content/uploads/2010/09/connect.png&quot; alt=&quot;&quot; width=&quot;694&quot; height=&quot;335&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I bet the same can be done with &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms365247.aspx&quot; target=&quot;_blank&quot;&gt;SQL Server Management Studio Express&lt;/a&gt; but I have yet to install it.&lt;/p&gt;

</description>
                
                            <pubDate>Wed, 22 Sep 2010 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2010/09/22/how-to-import-a-database-schema-into-sql-server-express-with-visual-studio/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2010/09/22/how-to-import-a-database-schema-into-sql-server-express-with-visual-studio/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>PicasaUploader 0.5: Upload videos</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I have released version 0.5 of &lt;a href=&quot;http://ivanz.com/projects/picasauploader/&quot;&gt;PicasaUploader &lt;/a&gt;– the simple PicasaWeb uploader tool. Changes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add support for uploading videos.
    &lt;ul&gt;
      &lt;li&gt;Supported files are: .avi, .mpeg, .mpg, .wmv, .3gp, .asf, .mp4, .mov. However PicasaWeb can still reject any of those if it doesn’t like it. Note also that videos won’t be playable in the album immediately because they have to be postprocessed by PicasaWeb.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;File size limits: 20MB for photo files and 100MB for video files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get it &lt;a href=&quot;http://ivanz.com/projects/picasauploader/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div id=&quot;attachment_719&quot; style=&quot;width: 310px&quot; class=&quot;wp-caption aligncenter&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2009/04/video-upload1.png&quot;&gt;&lt;img class=&quot;size-medium wp-image-719&quot; title=&quot;Video Upload&quot; src=&quot;http://ivanz.com/wp-content/uploads/2009/04/video-upload1-300x221.png&quot; alt=&quot;Video Upload&quot; width=&quot;300&quot; height=&quot;221&quot; /&gt;&lt;/a&gt;
  
  &lt;p class=&quot;wp-caption-text&quot;&gt;
    Video Upload
  &lt;/p&gt;
&lt;/div&gt;

</description>
                
                            <pubDate>Sat, 05 Jun 2010 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2010/06/05/picasauploader-0-5-upload-videos/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2010/06/05/picasauploader-0-5-upload-videos/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>IBM</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I started at IBM UK (Hursley Labs) on Monday but it is only today that I got my permanent badge with all the security clearance added for the ultra confidential work I will be doing. 😀 One of the goodies when working in the restricted area is that only the chosen ones get access to the proper coffee machine which makes excellent espresso coffee only 10p each.&lt;/p&gt;

&lt;div id=&quot;attachment_712&quot; style=&quot;width: 317px&quot; class=&quot;wp-caption aligncenter&quot;&gt;
  &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2010/03/IMG_1933.jpg&quot;&gt;&lt;img class=&quot;size-medium wp-image-712&quot; title=&quot;IBM&quot; src=&quot;http://ivanz.com/wp-content/uploads/2010/03/IMG_1933-225x300.jpg&quot; alt=&quot;IBM&quot; width=&quot;307&quot; height=&quot;410&quot; /&gt;&lt;/a&gt;
  
  &lt;p class=&quot;wp-caption-text&quot;&gt;
    IBM
  &lt;/p&gt;
&lt;/div&gt;
</description>
                
                            <pubDate>Tue, 02 Mar 2010 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2010/03/02/ibm/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2010/03/02/ibm/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Three new featurelets for Fluent NHibernate</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Lately I have been using &lt;a href=&quot;http://fluentnhibernate.org/&quot;&gt;Fluent NHibernate&lt;/a&gt; and &lt;a href=&quot;http://nhforge.org&quot;&gt;NHibernate&lt;/a&gt; respectively for my ORM (Object-Relational Mapping) when working on my top secret pet project. Simply put – it’s great. Mapping is done using a fluent C# interface which makes use of lambda expressions for referencing properties instead of strings (check my &lt;a href=&quot;http://ivanz.com/2009/12/04/how-to-avoid-passing-property-names-as-strings-using-c-3-0-expression-trees/&quot;&gt;previous post&lt;/a&gt; for more info) so the domain model is &lt;strong&gt;safe to refactor&lt;/strong&gt; because the mapping will be kept up-to-date too.&lt;/p&gt;

&lt;p&gt;I spend some time hacking on Fluent NHibernate to add three little features I needed for my integration unit testing via Fluent NHibernate’s &lt;em&gt;PersistenceSpecification&lt;/em&gt;. They all currently live in my GitHub(also used by Fluent NHibernate) fork &lt;a href=&quot;http://github.com/ivanz/fluent-nhibernate&quot;&gt;here&lt;/a&gt; and have all been submitted upstream. &lt;strong&gt;UPDATE:&lt;/strong&gt; The changes are as of now (21.12.2009) officially part of Fluent NHibernate. I can only hope you will find them useful as well.&lt;/p&gt;

&lt;h3 id=&quot;persistencespecification-more-informational-error-reporting&quot;&gt;PersistenceSpecification: More Informational Error Reporting&lt;/h3&gt;

&lt;p&gt;Particularly useful to troubleshoot failing mapping integration unit tests when a property check fails it will print both expected and actual types of the values. Also notice that chained properties (object.PropA.PropB) are now supported as well:&lt;/p&gt;

&lt;p style=&quot;padding-left: 30px;&quot;&gt;
  &lt;em&gt;For property &amp;#8216;Nutrition.Calories&amp;#8217; expected &amp;#8216;400&amp;#8217; of type &amp;#8216;System.Int32&amp;#8242; but got &amp;#8216;400&amp;#8217; of type &amp;#8216;System.Single&amp;#8217;.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;instead of:&lt;/p&gt;

&lt;p style=&quot;padding-left: 30px;&quot;&gt;
  &lt;em&gt;Expected &amp;#8216;400&amp;#8217; but got &amp;#8216;400&amp;#8217; for Property &amp;#8216;NutritionCalories&amp;#8217;&lt;/em&gt;
&lt;/p&gt;

&lt;h3 id=&quot;persistencespecification-entity-components-property-testing&quot;&gt;PersistenceSpecification: Entity Components Property Testing&lt;/h3&gt;

&lt;p&gt;It is now possible to test entity component properties. For example given this domain model:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class Food
{
    public Food ()
    {
        Nutrition = new NutritionInfo ();
    }

    public virtual NutritionInfo Nutrition { get; protected set }
    public virtual int Id { get; set; }

}

public class NutritionInfo
{
    public virtual float? Fat { get; set; }
}

&lt;/pre&gt;

&lt;p&gt;and this mapping:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class FoodMap : ClassMap&amp;lt;Food&amp;gt;
{
    public FoodMap ()
    {
        Id (food =&amp;gt; food.Id)
            .GeneratedBy.Native ();

        Component&amp;lt;NutritionInfo&amp;gt; (food =&amp;gt; food.Nutrition,
            mapping =&amp;gt; {
                mapping.Map (nutrition =&amp;gt; nutrition.Fat)
                    .Nullable ();
            }
        ).Access.BackingField ();
    }
}

&lt;/pre&gt;

&lt;p&gt;One can now use this in unit tests:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;[TestMethod]
public void Food_Mapping ()
{
    new PersistenceSpecification&amp;lt;Food&amp;gt; (Session)
    .CheckProperty (food =&amp;gt; food.Id, 1)
    .CheckProperty (food =&amp;gt; food.Nutrition.Fat, 40f) // &amp;lt;-- This one
    .VerifyTheMappings ();

}

&lt;/pre&gt;

&lt;p&gt;Prior to my patch this wasn’t possible because Fluent Nhibernate &lt;em&gt;PersistenceSpecification&lt;/em&gt; did not support chained properties and was trying to set a &lt;em&gt;Fat&lt;/em&gt; property on the &lt;em&gt;food&lt;/em&gt; object. Note that this is useful only for components and &lt;span style=&quot;text-decoration: underline;&quot;&gt;not&lt;/span&gt; references. For the latter *.CheckReference (…) *should be used which will also commit the reference to the Database before doing anything else.&lt;/p&gt;

&lt;h3 id=&quot;persistencespecification-iequalitycomparer-for-individual-properties&quot;&gt;PersistenceSpecification: IEqualityComparer for Individual Properties&lt;/h3&gt;

&lt;p&gt;Given the setup from above it is now possible to set an IEqualityComparer per property, e.g.:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;[TestMethod]
public void Serving_Mapping ()
{

    new PersistenceSpecification&amp;lt;Food&amp;gt; (Session, new EqualityComparerForAllProperties ())
    .CheckProperty (food =&amp;gt; food.Id, 1)
    .CheckProperty (food =&amp;gt; food.Nutrition.Fat, 40f, FloatEqualityComparer.Instance)
    .VerifyTheMappings ();
}

&lt;/pre&gt;

&lt;p&gt;If there is no comparer set for the property it will fall back to using the &lt;em&gt;EqualityComparerForAllProperties&lt;/em&gt; and if that is not specified it will just use Object.Equals.&lt;/p&gt;

</description>
                
                            <pubDate>Sun, 13 Dec 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/12/13/three-new-featurelets-for-fluent-nhibernate/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/12/13/three-new-featurelets-for-fluent-nhibernate/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>How to avoid passing property names as strings using C# 3.0 Expression Trees</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;Referencing property names via strings is evil. Consider this simplistic example:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;private int _myProperty;

public int MyProperty
{
    get { return _myProperty; }
    set {
        _myProperty = value;
        NotifyPropertyChanged (this, &quot;MyProperty&quot;)
    }
}

// Somewhere in a different project or file...
private void NotifyPropertyChanged (object sender, string propertyName)
{
    if (propertyName == &quot;MyProperty&quot;)
        Console.WriteLine (&quot;Property Changed&quot;);
}
&lt;/pre&gt;

&lt;p&gt;If at some point the property gets renamed the code will compile fine but a bug will be introduced as all those strings that contain the property name will remain unchanged. Evil.&lt;/p&gt;

&lt;p&gt;So I have been toying with NHibernate lately and yesterday I was writing some repositories. Let’s assume that theoretically they look like this:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class Repository &amp;lt;TEntity&amp;gt;
{
    public virtual TEntity FindById (object id)
    {
        ...
    }
}

public class UserRepository : Repository&amp;lt;User&amp;gt;
{
    public IList&amp;lt;User&amp;gt; FindByName (string name)
    {
        // query code
    }

    public IList&amp;lt;User&amp;gt; FindByEmail (string email)
    {
        // query code
    }
}
&lt;/pre&gt;

&lt;p&gt;Both *FindByName *and *FindByEmail *in *UserRepository *will in theory contain the same queries but with different parameters. However I don’t really want to have to write individual queries so I considered a utility method:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class Repository &amp;lt;TEntity&amp;gt;
{
    public virtual TEntity FindById (object id)
    {
        ...
    }

    protected virtual IList&amp;lt;TEntity&amp;gt; FindByProperty (string propertyName, object value)
    {
        string columnName = NHibernateUtil.GetPropertyColumnName&amp;lt;TEntity&amp;gt; (propertyName);

        // Query here, e.g: &quot;SELECT .... WHERE .... columnName = value&quot; , etc.
    }
}

public class UserRepository : Repository&amp;lt;User&amp;gt;
{
    public IList&amp;lt;User&amp;gt; FindByName (string name)
    {
        return base.FindByProperty (&quot;Name&quot;, name);
    }

    public IList&amp;lt;User&amp;gt; FindByEmail (string email)
    {
        return base.FindByProperty (&quot;Email&quot;, email);
    }
}
&lt;/pre&gt;

&lt;p&gt;Again this is very bad code and I hated the idea of it, so I sat down and started thinking. I remembered reading somewhere about C# 3.0 Expression Trees so I did some research. When using the special *Expression *type this seems to tell the compiler to create and expose an AST to us of e.g. a lambda function’s body, so if we pass a property reference expression we can parse the AST and extract the property name from there.&lt;/p&gt;

&lt;p&gt;The theory in practice:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public class UserRepository : Repository&amp;lt;User&amp;gt;
{
    public IList&amp;lt;User&amp;gt; FindByName (string name)
    {
        return base.FindByProperty (user =&amp;gt; user.Name, name);
    }

    public IList&amp;lt;User&amp;gt; FindByEmail (string email)
    {
        return base.FindByProperty (user =&amp;gt; user.Email, email);
    }
}

public class Repository &amp;lt;TEntity&amp;gt;
{
    public virtual TEntity FindById (object id)
    {
        ...
    }

    protected virtual IList&amp;lt;TEntity&amp;gt; FindByProperty (Expression&amp;lt;Func&amp;lt;TEntity, object&amp;gt;&amp;gt; propertyRefExpr,
                                                     object value)
    {
        string propertyName = GetPropertyName (propertyRefExpr);

        // Query code
    }

    private string GetPropertyName (Expression propertyRefExpr)
    {
        if (propertyRefExpr == null)
            throw new ArgumentNullException (&quot;propertyRefExpr&quot;, &quot;propertyRefExpr is null.&quot;);

        MemberExpression memberExpr = propertyRefExpr.Body as MemberExpression;
        if (memberExpr == null) {
            UnaryExpression unaryExpr = propertyRefExpr.Body as UnaryExpression;
            if (unaryExpr != null &amp;amp;&amp;amp; unaryExpr.NodeType == ExpressionType.Convert)
                memberExpr = unaryExpr.Operand as MemberExpression;
        }

        if (memberExpr != null &amp;amp;&amp;amp; memberExpr.Member.MemberType == MemberTypes.Property)
            return memberExpr.Member.Name;

        throw new ArgumentException (&quot;No property reference expression was found.&quot;,
                         &quot;propertyRefExpr&quot;);
    }
}
&lt;/pre&gt;

&lt;p&gt;Also as a helper class:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;public static class PropertyUtil
{
    public static string GetPropertyName&amp;lt;TObject&amp;gt; (this TObject type,
                                                   Expression&amp;lt;Func&amp;lt;TObject, object&amp;gt;&amp;gt; propertyRefExpr)
    {
        return GetPropertyNameCore (propertyRefExpr.Body);
    }

    public static string GetName&amp;lt;TObject&amp;gt; (Expression&amp;lt;Func&amp;lt;TObject, object&amp;gt;&amp;gt; propertyRefExpr)
    {
        return GetPropertyNameCore (propertyRefExpr.Body);
    }

    private static string GetPropertyNameCore (Expression propertyRefExpr)
    {
        if (propertyRefExpr == null)
            throw new ArgumentNullException (&quot;propertyRefExpr&quot;, &quot;propertyRefExpr is null.&quot;);

        MemberExpression memberExpr = propertyRefExpr as MemberExpression;
        if (memberExpr == null) {
            UnaryExpression unaryExpr = propertyRefExpr as UnaryExpression;
            if (unaryExpr != null &amp;amp;&amp;amp; unaryExpr.NodeType == ExpressionType.Convert)
                memberExpr = unaryExpr.Operand as MemberExpression;
        }

        if (memberExpr != null &amp;amp;&amp;amp; memberExpr.Member.MemberType == MemberTypes.Property)
            return memberExpr.Member.Name;

        throw new ArgumentException (&quot;No property reference expression was found.&quot;,
                         &quot;propertyRefExpr&quot;);
    }
}
&lt;/pre&gt;

&lt;p&gt;As you can see it contains two generic methods that operate either on types:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;string propertyName = PropertyUtil.GetName&amp;lt;User&amp;gt; (u =&amp;gt; u.Email);
&lt;/pre&gt;

&lt;p&gt;or instances:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp; title: ; notranslate&quot; title=&quot;&quot;&gt;User user = GetUser();
string propertyName = user.GetPropertyName (u =&amp;gt; u.Email);
&lt;/pre&gt;

&lt;p&gt;Great, isn’t it? And safe to refactor.&lt;/p&gt;

&lt;p&gt;Of course there is no such thing as a free lunch and the use of expression trees comes at the expense of some performance.&lt;/p&gt;

&lt;p&gt;BTW is the font size of the code snippets sufficiently readable or is it too tiny?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Added support for Convert expressions (implicit/explicit casting)&lt;/p&gt;
</description>
                
                            <pubDate>Fri, 04 Dec 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/12/04/how-to-avoid-passing-property-names-as-strings-using-c-3-0-expression-trees/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/12/04/how-to-avoid-passing-property-names-as-strings-using-c-3-0-expression-trees/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>HowTo Disable the Unsigned Security Warnings on Windows Mobile</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;The security warnings when deploying unsigned applications from Visual Studio to a real Windows Mobile device can get very annoying. Thankfully they can be disabled with a hack and here is how.&lt;/p&gt;

&lt;p&gt;Using the Remote Registry Editor supplied with Visual Studio and with the Windows Mobile SDK installed change the following key value from 0 to 1 (and vise-versa to reset the change)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HKEY_LOCAL_MACHINE\Security\Policies\Policies\0000101a = 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it.&lt;/p&gt;
</description>
                
                            <pubDate>Sat, 15 Aug 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/08/15/howto-disable-the-unsigned-security-warnings-on-windows-mobile/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/08/15/howto-disable-the-unsigned-security-warnings-on-windows-mobile/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>msysGit Tip: Files Constantly Reported as Modified Fix</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I copied my Mono mcs Git working copy from Linux to Windows for use with MSysGit only to find out that even after &lt;em&gt;git reset –hard&lt;/em&gt; almost all files were being reported as modified by &lt;em&gt;git status&lt;/em&gt;. It turns out it has to do with the file permissions (executable bit I think) and the inability of msysgit to apply them on Windows.&lt;/p&gt;

&lt;pre&gt;$ git diff class/Accessibility/makefile.build
diff --git a/class/Accessibility/makefile.build b/class/Accessibility/makefile
old mode 100755
new mode 100644&lt;/pre&gt;

&lt;p&gt;The fix is to make git ignore some file mode stuff via:&lt;/p&gt;

&lt;pre&gt;git config core.fileMode false&lt;/pre&gt;

&lt;p&gt;Another useful setting on Windows is:&lt;/p&gt;

&lt;pre&gt;git config core.autocrlf true&lt;/pre&gt;
</description>
                
                            <pubDate>Sat, 18 Jul 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/07/18/msysgit-tip-files-constantly-reported-as-modified-fix/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/07/18/msysgit-tip-files-constantly-reported-as-modified-fix/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Multiple Network Connections at the Same Time on Windows</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;In my scenario I have one Wireless connection for my Internet and one LAN connection to a small private network of my own with my NAS, PS3 and TV and I want to have them both at the same time. It was a major pain to get this setup working on Windows. When I had both connections enabled my Internet wasn’t working because Windows was routing through the LAN connection even though the Wireless connection had a higher priority set in &lt;em&gt;Network Connections&lt;/em&gt; –&amp;gt; &lt;em&gt;Advanced&lt;/em&gt; menu –&amp;gt; &lt;em&gt;Advanced settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The solution is to go into the *Properties *of each connection (right click on it) –&amp;gt; select *Internet Protocol (TCP/IP) *–&amp;gt; click *Properties *-&amp;gt; click *Advanced *–&amp;gt; uncheck *Automatic metric *in the bottom and set a number between 1 and 9999 where the smaller the number the higher the connection priority. I have set my Wireless Internet connection to 1 and my LAN connection to 9999 and that works.&lt;/p&gt;

&lt;p&gt;I hope this post will save someone else’s precious time in the future.&lt;/p&gt;
</description>
                
                            <pubDate>Wed, 08 Jul 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/07/08/multiple-network-connections-at-the-same-time-on-windows/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/07/08/multiple-network-connections-at-the-same-time-on-windows/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>Visual Studio 2008 jQuery IntelliSense Fix</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I am tinkering with ASP.NET MVC and jQuery and making my first baby steps in a whole new horrible world of web development. I found out that the JavaScript IntelliSense in Visual Studio 2008 is broken out of the box. The error is:&lt;/p&gt;

&lt;pre&gt;Warning    2    Error updating JScript IntelliSense: jquery-1.3.2.js:
   Object doesn&apos;t support this property or method @ 2173:1&lt;/pre&gt;

&lt;p&gt;The fix for Visual Studio 2008 SP1 by Microsoft can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://code.msdn.microsoft.com/KB958502&quot;&gt;KB958502 – JScript Editor support for “-vsdoc.js” IntelliSense doc. files&lt;/a&gt;&lt;/p&gt;

</description>
                
                            <pubDate>Wed, 01 Jul 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>PicasaUploader 0.3: Batch Image Scaling/Resizing</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I have just released version 0.3 of my PicasaWeb Uploader tool. The new things are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;High quality batch image resizing/scaling on the fly prior to upload.&lt;/li&gt;
  &lt;li&gt;Memory usage performance improvements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get it from (and also for more information): &lt;a href=&quot;http://ivanz.com/projects/picasauploader/&quot;&gt;http://i-&lt;/a&gt;&lt;a href=&quot;http://ivanz.com/projects/picasauploader/&quot;&gt;nz.net/projects/picasauploader&lt;/a&gt;&amp;lt;/p&amp;gt;&lt;/p&gt;

&lt;div id=&quot;attachment_570&quot; style=&quot;width: 533px&quot; class=&quot;wp-caption aligncenter&quot;&gt;
  &amp;lt;/a&amp;gt;&lt;a rel=&quot;attachment wp-att-570&quot; href=&quot;http://ivanz.com/wp-content/uploads/2009/06/resize-photos.png&quot;&gt;&lt;img class=&quot;size-full wp-image-570&quot; title=&quot;Photo Resize&quot; src=&quot;http://ivanz.com/wp-content/uploads/2009/06/resize-photos.png&quot; alt=&quot;Photo Resize&quot; width=&quot;523&quot; height=&quot;412&quot; /&gt;&lt;/a&gt;
  
  &lt;p class=&quot;wp-caption-text&quot;&gt;
    Photo Resize
  &lt;/p&gt;
&lt;/div&gt;

</description>
                
                            <pubDate>Mon, 01 Jun 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/06/01/picasauploader-03-batch-image-scalingresizing/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/06/01/picasauploader-03-batch-image-scalingresizing/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
            <item>
                <title>PicasaUploader 0.2: A simple upload tool for PicasaWeb</title>
                <dc:creator></dc:creator>
                
                    <description>&lt;p&gt;I have just released version 0.2 of my PicasaWeb Uploader tool. The new things are “&lt;em&gt;Send To&lt;/em&gt;” right-click integration on Windows and username/password saving. Get it from (and also for more information): &lt;a href=&quot;http://ivanz.com/projects/picasauploader/&quot;&gt;http://ivanz.com/projects/picasauploader&lt;/a&gt;.&lt;/p&gt;

&lt;div id=&quot;gallery-7&quot; class=&quot;gallery galleryid-558 gallery-columns-3 gallery-size-thumbnail&quot;&gt;
  &lt;dl class=&quot;gallery-item&quot;&gt;
    &lt;dt class=&quot;gallery-icon landscape&quot;&gt;
      &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2009/05/albums-screenshot1.png&quot;&gt;&lt;img width=&quot;150&quot; height=&quot;150&quot; src=&quot;http://ivanz.com/wp-content/uploads/2009/05/albums-screenshot1-150x150.png&quot; class=&quot;attachment-thumbnail&quot; alt=&quot;albums-screenshot1&quot; /&gt;&lt;/a&gt;
    &lt;/dt&gt;
  &lt;/dl&gt;
  
  &lt;dl class=&quot;gallery-item&quot;&gt;
    &lt;dt class=&quot;gallery-icon landscape&quot;&gt;
      &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2009/05/photos-screenshot1.png&quot;&gt;&lt;img width=&quot;150&quot; height=&quot;150&quot; src=&quot;http://ivanz.com/wp-content/uploads/2009/05/photos-screenshot1-150x150.png&quot; class=&quot;attachment-thumbnail&quot; alt=&quot;photos-screenshot1&quot; /&gt;&lt;/a&gt;
    &lt;/dt&gt;
  &lt;/dl&gt;
  
  &lt;dl class=&quot;gallery-item&quot;&gt;
    &lt;dt class=&quot;gallery-icon portrait&quot;&gt;
      &lt;a href=&quot;http://ivanz.com/wp-content/uploads/2009/05/send-to-integration.png&quot;&gt;&lt;img width=&quot;150&quot; height=&quot;150&quot; src=&quot;http://ivanz.com/wp-content/uploads/2009/05/send-to-integration-150x150.png&quot; class=&quot;attachment-thumbnail&quot; alt=&quot;send-to-integration&quot; /&gt;&lt;/a&gt;
    &lt;/dt&gt;
  &lt;/dl&gt;
  
  &lt;br style=&quot;clear: both&quot; /&gt;
&lt;/div&gt;

</description>
                
                            <pubDate>Fri, 15 May 2009 00:00:00 +0000</pubDate>
                <link>http://ivanz.com/2009/05/15/picasauploader-02-a-simple-upload-tool-for-picasaweb/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</link>
                <guid isPermaLink="true">http://ivanz.com/2009/05/15/picasauploader-02-a-simple-upload-tool-for-picasaweb/?utm_source=blog&amp;utm_medium=rss&amp;utm_campaign=c1</guid>
            </item>
        
    </channel>
</rss>
