Watch out for Singletons

If you are a seasoned Episerver developer, you should (and probably, already) know about the foundation of the framework: dependency injection. With the Inversion of control framework (most common, Structuremap, but recent versions of Framework allow much more flexible options), you can easily register your implementations, without having to manually create each and every instance by new operator. Sounds great, right? Yes it is.

And Episerver Framework allows you to make it even easier by this nice ServiceConfiguration attribute:

[ServiceConfiguration]
public class MyClass 
{
}

so your class will be automatically registered, and whenever you need an instance of MyClass, IoC framework will get the best instance for you, automatically, without breaking a sweat. Isn’t it nice? Yes it is.

But I guess you also saw this from place to place

[ServiceConfiguration(LifeCycle = ServiceInstanceScope.Singleton)]
public class MyClass 
{
}

So instead of creating a new instance every time you ask it to, IoC framework only creates the instance once and reuses it every time. You must think to yourself: even nicer, that would save you a lot of time and memory.

But is it (nicer)?

You might want to think again.

Singleton means one thing: shared state (or even worse, Global state). When a class is marked with Singleton, the instance of that class is supposed to be shared across the site. The upside, is, well, if your constructor is expensive to create, you can avoid just that. The downside, of course, shared state can be a real b*tch and it might come back to bite you. What if MyClass holds the customer address of current user. If I set my address to that, and because you get the same instance, you’ll gonna see mine. In Sweden it’s not a real problem as you can easily know where I live (even my birthday if you want to send a gift, or flowers), but I guess in the bigger parts of the world that is a serious privacy problem. And what if it’s not just address?

And it’s not just that, Singleton also make things complicated with “inherited singleton”. Let’s take a look at previous example. Now we see Singleton is bad, so let’s remove that on our class. But what if other class depends on our little MyClass:

[ServiceConfiguration(LifeCycle = ServiceInstanceScope.Singleton)]
public class MyOtherClass 
{
   private MyClass _myClass;
   public MyOtherClass(MyClass myClass)
   {
        _myClass = myClass;
   }
}

Now I hope you see where the problem is. One instance of MyOtherClass is shared inside the side. And it comes with an attached MyClass instance. Even if you don’t intend to, that MyClass instance will also be shared. Same problem after all.

Singleton was there to solve one problem (or two), but it can also introduce other problems if you don’t really think about if your instance should be shared or not. And not just your class, the classes which have dependency on your class as well.

And it’s not just Singleton , HttpContext and Hybrid might also subject to same problem, but to a lesser extend. Any lifecycle that shares state should be considered: if you really need it and what you are sharing.

Lifecycle is hard, but it can also work wonder, so please take your time to make it right. It’s worth it.

Multiple catalogs: Without catalog name(s)

My previous blog posts about multiple catalogs in multiple sites setting here and here has helped one customer (hopefully more) to address their problem. They tried the approach and it works for them. Now they came back and ask if they can remove the catalog name from the URL entirely. Is that something that can be done. Fortunately, yes.

Before moving on, let’s be clear: this is obviously custom development and is not officially supported by Episerver. I.e. it’s neither tested and documented. Normally you would have to go to Expert Services for such requirement. For this blog, I provide those samples for free (you don’t even have to buy my book 😉 ), but remember I can only do that much. You have to test to see if it works for you (I of course do the basic testing), and if you run into problems later, I might not be able/available to help.

Now get back to the problem. Previously the router looks like this

    
protected override CatalogContentBase FindNextContentInSegmentPair(CatalogContentBase catalogContent, SegmentPair segmentPair,
        SegmentContext segmentContext, CultureInfo cultureInfo)
    {
        if (catalogContent.ContentType == CatalogContentType.Root)
        {
            CatalogContent definedCatalogContent;
            var definedCatalogLink = _contentLoader.Get(RouteStartingPoint).CatalogLink;
            if (_contentLoader.TryGet(definedCatalogLink, cultureInfo, out definedCatalogContent))
            {
                return definedCatalogContent;
            }
        }
        return base.FindNextContentInSegmentPair(catalogContent, segmentPair, segmentContext, cultureInfo);
    }

And it works great with  http://commerceref/en/fashion/mens/mens-shoes/p-36127195/ or http://commerceref/en/products/mens/mens-shoes/p-36127195/. But now they want to completely remove the catalog name from the url. They can’t make it works with http://commerceref/en/mens/mens-shoes/p-36127195/.

Why? Because the router is returning the catalog for /mens/ segment. In next segment (mens-shoes), we fallback to the default implementation, which can’t find any matching content as children of that definedCatalogContent .

The solution: Because we want the first-level category to appear as direct child of the catalog root, we would have to return it ourselves. Instead of returning the catalog, we return the first node that matches /mens/ segment.

        protected override CatalogContentBase FindNextContentInSegmentPair(CatalogContentBase catalogContent, SegmentPair segmentPair,
            SegmentContext segmentContext, CultureInfo cultureInfo)
        {
            if (catalogContent.ContentType == CatalogContentType.Root)
            {
                CatalogContent definedCatalogContent;
                var definedCatalogLink = _contentLoader.Get<StartPage>(RouteStartingPoint).CatalogLink;
                if (_contentLoader.TryGet<CatalogContent>(definedCatalogLink, cultureInfo, out definedCatalogContent))
                {
                    var nodes = _contentLoader.GetChildren<NodeContent>(definedCatalogLink);
                    return nodes.FirstOrDefault(n => n.RouteSegment.Equals(segmentPair.Next, StringComparison.OrdinalIgnoreCase));
                }

                return null;
            }
            return base.FindNextContentInSegmentPair(catalogContent, segmentPair, segmentContext, cultureInfo);
        }

And it just works:

Now that’s just one part of the solution. We still need to make sure outgoing URLs respect that. I’ll leave that to you, as practice.

Super short review of Mario + Rabbids: Kingdom Battle

Mario + Rabbids: Kingdom Battle is the second Switch game I played, and the first one I actually enjoyed.

Plus:

  • It’s a Mario game
  • Beautiful and vibrant world designs.
  • In fact it might be the most cute game I’ve played. Can’t wait to play it with my children (but given it’s rated ESRB 7+, it’ll be quite some time.
  • It’s XCOM without creepy creatures and scary moments. It does not have the strategy/tactical depth XCOM 2 has to provide, but it’s fun nonetheless.
  • It’s easy to restart a battle and play differently for different outcome.
  • The game is, surprisingly, smooth on Switch. Can’t say the same for XCOM 2 on PS4. I have to give credit to Ubisoft for this.

Minus:

  • As other Mario game, it’s not voiced.
  • Finding ways can be frustrating some times.
  • Some puzzles are more confusing than funny
  • Dragging end – you have battle after battle toward the end, which can be tiring for both you and the team.

All in all, it’s a fun game regardless and one I can recommend to Switch’s owners. 9/10.

Super short review of God of War PS4

One of the iconic characters on PlayStation, Kratos is known for his super violent nature, a tragedy past of betrayal, a thirst for revenge – and God of War is known for its brutal combat when you kill your enemies in most violent ways possible. The last major game in the series was God Of War 3 on PS3, released in 2011. 7 years is a long time to wait – and did Sony Santa Monica soft reboot of the series live up with the expectations?

I’m happy to say, it does, and some more. I’m still early hours into the game, but yet I’m very impressed. An older Kratos who is now a father, accompanied by his boy Atreus to fulfill Atreus’ mother’s last wish. And their journey begins.

This is Sparta!

Plus:

  • Violent, brutal, extreme satisfying combat. Animations are very well done. Yes, if you are looking for a God of War, here it is. Kratos is older, and he might not as fast or agile as he used to be, but his combat skills haven’t aged one bit. He still kills.
  • Excellent world design, exploring is both interesting and rewarding. Santa Monica Studio also did a great job adding lore and Norse mythologies into the game. Nothing feels forced, at all.
  • Beautiful characters and landscape. Horizon Zero Dawn set the bar very high for graphics, yet God Of War managed to even exceed that, in many ways.
  • Excellent character design. Kratos is obviously older, he is still strong and brutal, but he is slower and more grumpy. It feels so real.
  • A story you can believe. Some reviewers complained about Atreus. Come on, he is just a boy. Were they children, at all? He lost his mother, and then (supposedly) suddenly gets a father, who can be grumpy. There’s no doubt that Atreus will try hard to get his father’s approvals. I find his performance very good.
  • Leviathan is probably one of the coolest weapon in games, ever. Easy to use, great in melee combat and superb in ranged combat. Also super useful for opening gates, bridges and puzzles. The gameplay and puzzles are built around the weapon, so it feels so good to use.
  • Smart little puzzles/challenges.

Minus:

  • None yet. Or rather a small one: The photo mode feature (which was added as an update, was not available at launch) is quite hidden. Wish there was a way to quickly enter it, but that I can live with.

If I’m to give a score now, it’s a 9.5/10. I expect it will raise even higher because the combats should get even better and the story might contain some twists that make it’s worth it.

Index or no index, that’s the question

If you do (and you should) care about your Episerver Commerce site performance, you probably know that database access is usually the bottleneck. Allowing SQL Server works smoothly and effectively is a very important key to the great performance.

We are of course, very well aware of this fact, and we have spent a considerable amount of time making sure Commerce database works as fast as we could. Better table schema, better stored procedures, better indexes, … we have done all of that and will continue doing so when we have the chances. (And if you find anything that can be improved, you are very welcome to share your finding with us)

But there are places where the database performance improvement is in your hand.

Continue reading “Index or no index, that’s the question”

A super short review of Xenoblade Chronicles 2

I’m still just 1/3 way through the game. Here’s some of my thoughts so far

Hit:

  • Gorgeous world. No it’s not the level of graphic detail of Horizon Zero Dawn, but given Switch’s processing power, the game looks absolutely amazing.
  • Pyra is really cute (Talking about her face)

Miss

  • Pyra is overly sexualized. .Does Monolith need to let her wear a thong into battle. While it’s common in Japanese Role Playing Games (“fans service”, they said), it’s not what gaming should be.
  • The fetch quests are really, really boring. They need to die.
  • Looting is tedious. Too many “collection points”, too little value or interest for each of them.
  • The enemies really lack of diversity, Well, they have plenty of beasts in the game, but they way you kill them are no different at all. Combats are pretty much the same. Wait for this then press this button. Bah.
  • Crafting is not that fun.

WTF

  • The characters are super talkative during the combats. All 6 of them!

My friend told me the game will get much better in chapter 4 and 5, especially in combats, so I’m trying. But right now, I would give it a 7. Or a 7.5, for Pyra.

Why I left Metacritic, for good.

I’m a mediocre gamer, by any measures, but that does not defy the fact that I love playing games. Great games, only. With my very limited time and budget, I must to be very selective about the games I play. For a very long time, Metacritic is my to-go website to check if I should play a game – and I set my rules rather high: anything less than 80 is a big no-no. Less than 85 is a no, unless it’s a sequel of a game I loved so much (so I can see how the story turned out to be). More than 85 is “I’ll think about it” (when it comes with a very tempting discount, I might make up my mind). A game of at least 90 Metacritic score will be in my short list (but not necessary in my playing list). A game of at least 95 Metacritic means “must try” for me. I might not love it, but a game with such reviews must have something I like about.

However, overtime, I did realize what MetaCritic is really meant to be, and why reviews can be full of sh*t.

Game reviews, as almost other content in the Internet, include the post you are reading, are opinions. It’s opinion, just like you and me, but the only thing that makes critics stand out is professionalism.

But that’s not something I’ve seen in many reviews which are listed on Metacritic.

You can either love, or hate a game. You can talk about it, openly, it’s your rights! But if you want to help your readers decide if they should  buy or play the game, based on your judgement, you have to be fair. Your opinions have to be as objective as possible. Of course, there is no such thing as “true objective” in reviews, but yours should have a reasonable amount in them.

Unfortunately, in this area of internet, clicks and views are everything. More views mean more ads impressions, ads clicks, and that mean more money.

The best known trick for clicks, is of course, controversial opinion.

Metacritic has a fairly easy review policy. The only measurable criteria is you have to have at least 30 reviews in your website, and you have to review fairly regularly. All other criteria about ethical or professionalism are indeed subjective. And that are being heavily abused.

Less known websites have been using that tactic to draw attention to their website. By giving a highly anticipated game an unreasonable low score, they create the controversy. People will urge to visit their websites to comment on the absurd review, or even sharing the reviews so their friends can attack them.

Who is benefiting? Do you have to guess?

Let’s talk about the infamous Washington Post’s Uncharted 4: A thief end review. Of 113 reviews averaging 93/100, they gave them 2/5 (equivalent to 40/100).

Or the slightly less infamous, USGamer’s Horizon: Zero Dawn review: 5/10 for a game which is otherwise rated 89/100.

Can you imagine it?

And Washington Post is not the only one. GameCritics, another less known site, has jumped in a gave the game a 50/100.

You can be harsh – that’s what famous magazine like Edge is known for – but you also need to be fair. You can criticize a game as much as you like, as long as the criticism is objective – why don’t you like it, and what it can have done better. When you bash a game because it’s not your taste, you become biased. The said review from WP was even disagreed by their staff

I’ve never disagreed more with a piece of content on our website as I have with this. haha  

The worst thing is this kind of shaggy tactic is not per review. Some sites are known to use it systematically, hoping to attract more clicks to the website:

GameCritics is just slightly better:

You see the pattern here? Well, you can expect those websites will, more often than not, give the lowest scores to a highly anticipated game, so their reviews become more visible and attract more clicks. People would go their and bash their review, like they themselves did with the game. In the end, who’s getting the benefits here?

Metacritic has changed the way we look at reviews. Before Metacritic, it’s more difficult to get a fairly balance, objective views of the game. But the good deed of Metacritic is being abused and if they don’t do anything to fight that, they will soon obsolete themselves.

Delete the undelete-able folder – Windows 7, 8, 10

If you are using Windows 7, 8, or 10, sometime there are some folders appear to be super stubborn, and refuse to go away. No matter how much you try, it just can’t be deleted. It’s undelete-able. Any attempts would result in this dreadful dialog box:

“Are you f*cking kidding me? This is my computer and I have the the absolute control over everything” – You said. Naturally, you would go to open the Security tab in Properties dialog to grant the permissions to everyone.

Strangely, the tab is empty! In other words, there is no one granted permission to nothing.

What? Why? How?

The truth is quite shocking: the folder might be already deleted – but there are processes still referring to it – and by that they keep the handle to the folder open. When that happens, you can’t really do anything to the folder without terminating the process first.

How to find the process then?

Just use Process Explorer, a free SysInternals tool from Microsoft.  Download, extract and run the .exe file (procexp.exe if you are running x86 version, or procexp64.exe if you are running 64 bit version of Windows) Click on Find/Find Handle or Dll, or use Ctrl+F shortcut. In this case we’re looking for typings, which is a fairly unique string. You can of course search by the path if the folder name is quite generic (i.e. there might be a lot of them). Wait for a little bit for this to show up. We got you the sneaky process(es):

Now you know which process is holding the handle to the folder, it’s as easy to fix it. Double click on the process and Process Explorer even let you know the parent process. In most of the cases you can have a peaceful exit and everything will be fixed. In worst cases, a forceful close might be needed.

 

Debuging React tests with Visual Studio Code

Visual Studio Code is awesome and it is getting more and more popular in front end development. It’s great to write code, but you know what, it can be an IDE and allow you to debug your tests as well:

Go to Debug/Add Configuration menu and add this setting:

{
	"version": "0.2.0",
	"configurations": [
		{
		  "name": "Debug JS Tests",
		  "type": "node",
		  "request": "launch",
		  "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts-ts",
		  "args": [
			  "test",
			 "--runInBand",
			 "--no-cache",
			 "--env=jsdom"
		  ],
		  "cwd": "${workspaceRoot}",
		  "protocol": "inspector",
		  "console": "integratedTerminal",
		  "internalConsoleOptions": "neverOpen"
		}
	]
}

You can see that we are invoke the react-scripts-ts command with test argument. This also means we are not limited to tests – but I’m yet to debug the normal code.

Now it’s important to remember: you have to open your root folder, in most of the cases, the parent folder of src, in Visual Studio Code. This is to make sure Visual Studio can access the node_modules folder, as well as it can access package.json if needed. I tried to open src folder and a bunch of errors were thrown to my face.

Now you can happily debug your React tests with VS Code:

 

Multiple sites: Building the outgoing URLs

In previous recipe we talked about multiple catalogs with same “UriSegment” – which we had a working implementation for incoming URL, i.e. when a customer visit a product url, we know which catalog we should choose from. But we still need to cover the generation of outgoing URL. I.e. when we link a product (For example, from a campaign page), we need to generate an URL which take the “catalog-less” pattern into account.

We need to understand how the outgoing URL is built. The hierarchical router builds the URL by the `RouteSegment` of contents. However, we want to the urls appear to have same catalog, so the `RouteSegment` part for the catalogs must be the same, regardless of the true catalogs. Because all catalogs are on same level, their `RouteSegment` must be unique – and this is enforced from Framework level (which is understandable, otherwise, how can it know which content to choose).

Continue reading “Multiple sites: Building the outgoing URLs”