Do not misuse or over abstract AutoMapper

November 27, 2016 AutoMapper, Opinion 13 comments

AutoMapper is a great little library every .NET project is using (well, lots of them). I used it for the first time in 2010 and wrote a blog post about it.

Since that time I observed few things:

  • Almost every project I worked on, that needed some kind of object mapping, was using this lib. In rare cases there was some pet library or manual mapping in place.
  • Almost every project had some abstraction over the library like if it was going to be replaced or like different implementation for mapping would be needed.
  • Basic API of the library didn’t change at all. CreateMap and Map are still there and work the same. At the same time performance, testability, exception handling, and feature richness got improved significantly. Last one, in my opinion, is not such a good thing as it leads to the next point.
  • In many of those projects AutoMapper was simply misused as code placed in AfterMap or in different kinds of resolvers would simply start containg crazy things. In worst of those cases actual business logic was written in resolvers.

I have always been of an opinion:

Less Code – Less Bugs; Simple Code – Good Code.

Having seen this trend with the library, I would like to suggest simplifying its usage by limiting ourselves. Simply:

  • Use AutoMapper only for simple mapping. Basically, one property to one property. Preferably, majority of property mapping is done by the same name. If you find yourself in situation when over half of your mappings are specified explicitly in ForMember method it may be the case for doing it manually (at least for the specific type) – it will be cleaner and less confusing.
  • If you have some logic to add to you mapping, do not add it via AutoMapper. Write a separate interface/class and use it (via DI) where your logic has to be applied. You will also be able to test it nicely in this way.
  • Do not abstract AutoMapper behind interfaces/implementations. I’ve seen abstracting this in a way that you need to create a class (empty in many cases) for each mapping type pair and somewhere there would be custom reflection code that initializes all of the mappings. Instead, use built-in AutoMapper Profile class and Mapper.Initialize method. If you still want to have at least some abstraction to avoid referencing AutoMapper everywhere make it simple.

Here is how I’m using AutoMapper these days:

Somewhere in CommonAssembly a very-very simple abstraction (optional):

Somewhere in BusinessLogicAssembly and any other where you want to define mappings (can be split in as many profiles as needed):

Somewhere in startup code in BootstrappingAssembly (Global.asax etc):

And here is the usage:

That’s it. I do not understand why some simple things are made complex.

There is also another advantage of keeping it minimalistic – maintainability. I’m working on a relatively new project that was created from a company’s template, as a result it had older version of AutoMapper abstracted. To upgrade it and keep all old interfaces would mean some work as abstraction used some of the APIs that did change. Instead I threw away all of these abstractions and upgraded the lib. Next time upgrading there simply will be way less code to worry about.

Please let me know if you share the same opinion.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


13 comments


Synch Two Git Repositories Using Bundle File And USB-stick

November 16, 2016 git, Tools No comments

Imagine working on the same code base in two disconnected networks. How would you synchronize your repositories using rudimentary storage device, like a USB-stick?

Undeniably for such a synchronization there could be multiple solutions starting with very primitive manual copying of cloned repositories finishing with some specialized devices and synch processes.

I came up with something intermediate, until the situation with the setup of project changes.

git-bundle-synch-on-usb-device

Idea is very simple:

1. USB-sharing device, so that USB-stick can be shared with a press of a button (physical in this case)

2. git bash script that does the following:

  • Tries to connect to both repositories to identify which one is accessible
  • Fetches sources from available repository
  • Fetches sources from bundle file on USB-stick (git bundle file is like a zip file with history and all files)
  • Tries to merge these two folders with flag –allow-unrelated-histories so that history is completely preserved
  • If merge succeeds it pushes changes to available repository and recreates bundle
  • If merge fails, you would need to manually resolve conflicts and push

3. A task to trigger the synch script when USB-stick with bundle is connected (I do not have this one yet, but it is a next logical step)

If two repositories were available at the same time the same script (with modifications) could be used to synchronize them on schedule or trigger event.

Here is the code of the script:

 

I also make it available on github under MIT license. Hopefully it comes in handy.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


No comments


Single Git Repository for Microservices

November 14, 2016 Opinion No comments

Just recently I joined a team. We write intranet web application. There is nothing too special about it, except that it was designed to be implemented as micro-services and as de-facto at the moment it is a classical single .NET MVC application. This happened for a simple reason: meeting first release deadline.

The design was reflected in how source control was set up: one git repository per each service. Unfortunately this caused a number of required maneuvers to be in synch and to push changes as team was making scattering changes in multiple repositories. This also made it more difficult to consolidate NuGet packages and other dependencies as all of them were in different repositories.

I think that microservices and corresponding hard reflection of their boundaries in form of source code repositories should evolve naturally. Starting with a single repository sounds more reasonable. If you keep the idea of microservices in you head and nicely decouple your code nothing stops you creating new repositories as you service boundaries start to make shape.

Taking this into account we merged repositories into one. There was only question of keeping source code history. Turns out the history can be easily preserved by employing git subtree command and placing all of the service repositories as subdirectories of a new single repository.

As a result, team is working much more effectively as we do not waste time on routine synch and checking who did what where. 

Conclusion: Theoretically micro-services should be implemented in their own repositories. That’s true, but in practice for relatively small and new project, with only one team working on it, single repository wins.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


No comments


Book Review: “The Black Swan”

October 30, 2016 Book Reviews No comments

The Black Swan - Book Cover

A black swan is a highly improbable event with three principal characteristics: It is unpredictable; it carries a massive impact; and, after the fact, we concoct an explanation that makes it appear less random, and more predictable, than it was. The astonishing success of Google was a black swan; so was 9/11. For Nassim Nicholas Taleb, black swans underlie almost everything about our world, from the rise of religions to events in our own personal lives.

Description by the publisher

I have listened to the audio version of “The Black Swan” twice. First time at the beginning of the year and the second time just recently. The book is philosophical in a way. It is not very easy to fully comprehend conveyed message as author frequently diverts to fictional stories, terms in French, and thinkers that are long time dead.

There were two striking statements in the book “anyone can be a president” if someone like “these people can get a Nobel prize”. Sounds actual? Think of Trump vs. Clinton presidential race and Bob Dylan receiving Nobel prize in Literature if you are not reading this in Autumn 2016.

bill-and-hillary-clinton-discuss-becoming-president

This does not mean that Nassim Taleb is any sort of predictor or prophesy maker. He himself says that he cannot make predictions, instead he highlights over and over again that rare events that seem improbable do occur more frequently than most of us would imagine and at the same time it is impossible to come up with mathematical models that would somehow calculate probabilities for these events. Unfortunately, we cannot know what we don’t know, therefore the best strategy for any of us is to build robustness to black swan events.

Application of the ideas expressed in the book is very wide. Starting with building financial portfolio consisting of 90% of very safe investments and 10% of extremely risky ones, therefore exposing yourself to probability of catching a black swan, like Google or Facebook. Ending with applying it to your life by exposing yourself to variety of endeavors. Careful here: event’s consequences are even harder to predict than occurrence of such events.

There is one aspect of the book that I don’t like. The author almost throughout the book despises other people imagining them as aggressive apes and suggesting nasty things like putting a rat down someones shirt. I do not exclude that he imagines his readers in the same way: silly monkeys reading higher caliber philosophical work. This, though, does not disqualify his book from being a really valuable contribution to human knowledge, but, in my opinion, it is only thanks to the black swan event of him benefiting from the 2000 crisis that made him successful and subsequently allowed him to write this and other books.

Conclusion

This book is definitely worth reading. It may make you look at the world as sequences of improbable events that change everything around. It could also make you way more skeptical about the theoretical modeling suggested by economists and other tie wearing experts. The book is not an easy read. On the contrary, it requires a lot of attention and thinking. Maybe leave it for a time when you are in a “philosophical” mood.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


No comments


How to add Microsoft.Extensions.DependencyInjection to OWIN Self-Hosted WebApi

October 17, 2016 .NET, HowTo, WebApi No comments

I could not find an example showing how to use Microsoft.Extensions.DependencyInjection as IoC in OWIN Self-Hosted WebApi, as a result here is this blog post.

Let’s imagine that you have WebApi that you intend to Self-Host using OWIN. This is fairly easy to do. All you will need to do is to use Microsoft.Owin.Hosting.WebApp.Start method and then have a bit of configuration on IAppBuilder (check out ServiceHost.cs and WebApiStartup.cs in the gist below).

It becomes a bit more complicated when you want to use an IoC container, as OWIN’s implementation takes care of creating Controller instances. To use another container you will need to tell the configuration to use implementation of IDependencyResolver (see WebApiStartup.cs and DefaultDependencyResolver.cs). DefaultDependencyResolver.cs is a very simple implementation of the resolver.

In case you are wondering what Microsoft.Extensions.DependencyInjection is. It is nothing more than a lightweight DI abstractions and basic implementation (github page). It is currently used in ASP.NET Core and EF Core, but nothing prevents you from using it in “normal” .NET. You can integrate it with more feature-rich IoC frameworks. At the moment it looks like Autofac has the best integration and nice documentation in place. See OWIN integration.

Rest is just usual IoC clutter. See the gist

I hope this blog post helps you with integrating Microsoft.Extensions.DependencyInjection in WebApi hosted via OWIN.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


No comments


Ember upgrade from 1.7.0 to 1.13.13

October 4, 2016 EmberJS No comments

EmberRelease Obviously there are general upgrade guides provided by Ember team and many fellow bloggers. This is just to document one of the experiences with upgrading from ember 1.7.0 to 1.13.13.

At the moment of this writing Ember latest stable version is 2.8. My team was one of the early adopters of Ember. I believe the team started incorporating it in late 2013, which is very soon after the 1.0 release. We went live with the version 1.7 at the beginning of 2015 and since that time we didn’t do any updates for “penny wise and pound foolish” reasons.

Upgrade itself was a bit of pain as it spread for couple of months. We allocated few days per sprint and at the same time continued developing new features the old way in other branches. Bad idea.

Another pain was that we adopted Ember Data while it was still beta. As a result we have custom code altering adapter’s and serializer’s behaviour. There are many breaking changes between beta versions of Ember Data, so using it while in beta was a very bad idea.

One of great things about being on Ember 1.13.13 version is that you are effectively on 2.0.0 version unless you have deprecation messages in your console. This also means that you can still release your application with some parts not being completely converted to the new way of doing things. ember.prod.js doesn’t generate warnings and works just fine. I really like the way Ember tries to make upgrading easy. Here is a nice write up on handling deprecations as of 2.3.0.

List of useful links:

Gotcha list:

This list is composed from notes I took so it is not very well organized and does not contain all of the items we had to fix.

When upgrading from 1.7 to 1.8

  • Update ember data to 1.0.0-beta.11 for compatibility and as a fix for “Ember Data cannot read property 'async' of undefined"
  • Replace pushObject with addRecord to fix “You looked up the relationship on a with id but some of the associated records were not loaded.”
  • This does not work and has to be rewritten Ember.Handlebars.helpers.render.call(this, name, contextString, options)
  • Use Ember.set() whenever there was controller.isNew property with some set

When upgrading from 1.8 to 1.10.1

  • Start using HTMLBars instead of Handlebars by incorporating ember-template-compiler
  • add stripBOM to grunt file… as template compiler includes those: template = template.replace(/\uFEFF/g, ''); // remove BOM
  • Fix HTML to be correct (closing tags, missing tbody, etc)
  • ember-data 1.0.0-beta.11 has bug in findQuery asserts => upgrade ember-data to 1.0.0.beta12
  • Remove //# sourceMappingURL=ember-data.js.map
  • Ensure models are generated with {async: false}
  • Remove code that works with MetamorphView. Fixes this: Assertion Failed: A fragment cannot be pushed into a buffer that contains content because of: view.createChildView(Ember._MetamorphView, {

When upgrading from 1.10.1 to 1.11.4

At this point you start to get tons of deprecation messages.

  • You attempted to access `someProperty` from `<App.SomeXyzController:ember2661>`, but object proxying is deprecated. Please use `model.someProperty` instead.
  • Convert this {{action bubbles=false preventDefault=false}} to this {{action "ok" "close" "cancel" bubbles=false preventDefault=false}}
  • Fix dynamic compilation of HTMLBars. Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`. Ember.HTMLBars.compile(submitHtmlTemplate); doesn’t produce a correct function to retrieve HTML. Can be solved as in this SO answer.
  • Using @each at the end of a computed key is deprecated and will not work in Ember 2.0
  • Replace Ember.Enumerable.mapProperty with mapBy
  • Replace Ember.Handlebars.helper with Ember.Helper.helper

When upgrading from 1.11.4 to 1.13.13

  • Rewrite code that uses itemController
  • Rewrite properties that have setter to the new computed syntax

I hope this comes in handy for you.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


No comments


Running Challenge Completed. Health, Motivation, and Other Aspects Of Running

October 2, 2016 Opinion No comments

Are you bent by scoliosis programmer? Do you spend too much time sitting? Maybe you look a bit flabby? Super tired at and after work? High chances are that some of these are true for you. Some certainly are true for me. This year I tried to improve my situation by running. Here are my thoughts and humble recommendations.

Dirty Running Shoes

Running and its impact on your Health

“Being physically active reduces the risk of heart disease, cancer and other diseases, potentially extending longevity.” – many studies show accordingly to this article. Probably one of the most accessible forms of exercising is running. All you need to start is just pair of shoes. This research paper is a good resource on learning about impact of running and other exercises on chronic diseases and general mortality.

So why running? – Because it is easy to start with and because we are made for it. “Humans can outrun nearly every other animal on the planet over long distances.” – says this article. Funnily enough there is yearly Human vs. Horse marathon competition.

If you ask yourself how you want your last two decades before death look like, most likely you would picture a healthy, mobile, and socially active person. Also you would prefer those two decades better be 80’s and 90’s. Right? Light running for as little as 1 hour a week could add as much as 6 years to your life. This long-term study showed that “the age-adjusted increase in survival with jogging was 6.2 years in men and 5.6 years in women.” (For those who are pedantic and want to know net win: (2 hrs/wk * 52 wks a year * 50 years) / 16 day hours = 325 days lost to running still gives you net 5 years).

Motivation

At my age I do not think about the death that much. My main motivation for running is improvement of my health. I know that for many people extra weight is motivating factor. For me it is not as instead of loosing weight I gained some 2-3 kg. Likely I’m so skinny there is no way to loose fat, though there is room for leg muscles growth. Unfortunately running is often boring and it is very hard to get yourself outside and go for a run on that nasty cold day. Here are few things that helped me running this year:

Run different routes

Always running at same location taking same path is boring. If you travel somewhere, just take your shoes with yourself and have a run at new place. Not only you get to have another run, but you explore the location. I ran in five different countries this year and could tell that those runs are more interesting than usual next to home ones.

Running in Ireland Gap Of Dunloe

Join friends or running club

I was going for runs rather rarely at the beginning of the year, but later as I started running with friends I started to run more frequently. It is always much more pleasant to have a conversation and learn few new things from friends, especially if areas of your interest overlap more than just running.

Running With Friends

Sign up for a challenge

Sports are competitive by nature. You can have friendly competition with your fellow runners, or you can take a virtual challenge. That works great because the clock is ticking and you want to have it done. This September I took it to the next level by signing up to Strava monthly challenges. I have completed all of them. See Trophy Case below:

Strava September Running Challenge

Be careful and avoid injury

You don’t want to walk with a cane when old because you were too stupid and run too much and too hard when young. I’m sick of running because of this September challenge. I completed it, but last two runs I ran through the pain being injured. I’m recovering now using RICE recovery technique. From now on I will take it easier. Suggesting the same for you.

RICE Recovery - Icing an Ankle

You can do it

I’m not a good runner. At the beginning of the year I could barely run 5km, I didn’t know how I will complete my planned 40 runs as it was so hard. Running 40 times was my main year goal. I did not expect that I will ran for around 50 times totaling 320 km. And it is not the end of the year yet. I also ran a Half-Marathon distance running a top Kahlenberg hill next to Vienna. If I can do it – you can!

Conclusion

I completely agree with research and studies that “for majority of people the benefits of running overweight the risks” and at the same time I voluntarily ran through the injury just to complete my challenge. Motivation is an important factor, but runners have to be careful and moderate their exercising. This is especially true if you run for the health reasons. Just try to make your runs more interesting and enjoy your life… longer.

Running under Speed sign

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone


No comments