Include/IncludeOn/Exclude/ExcludeOn: a simple explanation

When I come across this question https://world.episerver.com/forum/developer-forum/-Episerver-75-CMS/Thread-Container/2020/3/trouble-with-availablecontenttypesattribute-excludeonincludeon/ I was rather confused by the properties of AvailableContentTypesAttribute (admittedly I don’t use them that often!). Looking at the code that defined them, or the XML documentation does not really help. I only come to an understanding when I look into how they are used, and I guess many other developers, especially beginners, might have same confusion, so here’s a simple explanation.

Include : defines content types that can be created as children of a content of this type (being decorated by the attribute)

IncludeOn: defines content types that can be parent of a content of this type

Exclude: defines content types that can not be created as children of a content of this type

ExcludeOn: defines content types that can not be parent of a content of this type.

If there is a conflict between those properties, for example content type A has Include with content type B, and content type B has ExcludeOn with content type A, then Exclude and ExcludeOn take priority (i.e. they will override Include and IncludeOn. In the example above then content type B will not be able to be children of content type A)

While AvailableContentTypesAttribute is extremely helpful, the property naming is not the best – they are short and symmetric, but they are not easy to understand and remember. An “improved” example might be

CanBeParentOf

CanBeChildrenOf

CannotBeParentOf

CannotBeChildrenOf

Yes they are more verbose, but they are unambiguous and you will not have to check the document (or this blog post) when you use them.

This is not the first time we have something that rather confusing in our API. One notable example is the old (now removed) ILinksRepository with the Source and Target properties in Relation . For quite some time I always had to check the code to know what to use, and then had the documentation updated, and eventually, changed to Parent and Child. No API is created perfect, but we can improve over time.

Listing permissions per user/group

This week I came cross this question on Episerver World forum https://world.episerver.com/forum/developer-forum/Episerver-Commerce/Thread-Container/2019/5/get-rolepermission-data/ , and while it is not Commerce-related. it is quite interesting to solve. Perhaps this short post will help the original poster, as well future visitors.

As in the thread, I replied the first piece to solve the puzzle:


You can use PermissionTypeRepository to get the registered PermissionTypes, then PermissionRepository to figure out which groups/users have a specific permission 

If you want to list permissions granted to a specific role or user, it is just a simple reversion using a dictionary:

            var rolePermissionMap = new Dictionary<string, HashSet<PermissionType>>(StringComparer.OrdinalIgnoreCase);
            var permissionTypes = _permissionTypeRepository.List();
            foreach (var permissionType in permissionTypes)
            {
                var securityEntities = _permissionRepository.GetPermissions(permissionType);
                foreach (var securityEntity in securityEntities)
                {
                    if (rolePermissionMap.ContainsKey(securityEntity.Name))
                    {
                        rolePermissionMap[securityEntity.Name].Add(permissionType);
                    }
                    else
                    {
                        rolePermissionMap[securityEntity.Name] = new HashSet<PermissionType>() { permissionType };
                    }
                }
            }

As suggested above, we use
PermissionTypeRepository to list the registered PermissionType(s) , and then for each PermissionType we get the list of SecurityEntity it is granted for. A SecurityEntity can be an user, a group, or a virtual role, and is identified by the name. For purpose of demonstration, we only use names: For each SecurityEntity granted a permission, we check if it is in our dictionary already, if yes, then add the permission to the list, otherwise add a new entry.

Simple, eh?

Unless if you are assigning/un-assigning permissions a lot, it is probably a good idea to keep this Dictionary in cache for some time, because it is not exactly cheap to build.

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.

Episerver caching issue with .NET 4.7

Update 1: The bug is fixed in .NET 4.7.1 (thanks to Pascal van der Horst for the information)

Update 2: The related bug is fixed in CMS Core 10.10.2 and 9.12.5. If upgrading to that version is not an option, you can contact Episerver support service for further assistance.

Original post:

If you are using Episerver and update to .NET 4.7 (even involuntarily, such as you are using DXC/Azure to host your websites. Microsoft updated Azure to .NET 4.7 on June 26th) , you might notice some weird performance issues. If your servers are in Europe, Asia or Australia, then you can see a peak in memory usage. If your servers in North America, then you can see the number of database calls increased. In both cases, your website performance is affected, the former can cause your websites to constantly restarts as memory usage reaches a threshold limit, and even more obvious in the latter. Why?

It was a known issue in .NET 4.7, as mentioned here: https://support.microsoft.com/en-us/help/4035412/fix-expiration-time-issue-when-you-insert-items-by-using-the-cache-ins

Continue reading “Episerver caching issue with .NET 4.7”

Episerver CMS performance optimization – part 1

Update: In Episerver CMS 11, released today (November 21st 2017), the simpleaddress router has been moved to the last of the route table.

Original post:

This is an unusual post – it is not about Commerce – my area of expertise, but about CMS. Recently I’ve been working on some support cases where SQL Server instance is on high utilization, and in some scenarios it eventually slows down the site. After investigation, it’s likely to come from a small, simple and helpful feature: Simple address.

CMS content can have a property named “Simple address”, which allows you to create a “shortcut” url for that content. So if you have one page with “name in url” as “contact-us” under a page name “about-us” under Home page, you can access it via https://mysupercoolsite.com/en/about-us/contact-us. Or you can set the Simple address for that page as “contact-us”, and then you can access it directly via https://mysupercoolsite.com/contact-us.

Continue reading “Episerver CMS performance optimization – part 1”