Question

I'm working on a modular application in .NET using Unity and Prism V4. An advantage to having a modular design is the ability to easily add and remove features. It is a requirement that I am able to create versions of the application that add or exclude certain features. Using Prism and Unity, I can do this by loading the assemblies (.dll files) for the required features. I like this because it allows me to cleanly and precisely exclude an entire feature.

I have certain features which absolutely must not be included in some versions of the application for our own liability. I want to prevent a user from being able to copy another user's .DLL file into his directory to gain that functionality. Other people with similar concerns may be interested in selling "plugin modules" as upgrades to an additional product and limiting access to those who have purchased the add-on. This isn't quite what we are doing, but is also not to be completely ruled out.

Now, with Prism and Unity there are multiple ways to register the module catalog, including in code, from a directory, from an application configuration XML file, or you can write your own. One of the simplest methods is for the application's shell to reference each assembly and the code specifically loads the assembly files for that configuration. This does make it slightly more difficult to simply copy a file from someone else and get that feature. However, I'm afraid it could lead to the possibility of configuration mistakes, or prevent the more general purpose "add-on" scenario (i.e. you would need to recompile the application shell to include features).

If I hard code the assemblies to load, I'll probably have to #ifdef on a build environment variable to determine which modules should be loaded. This doesn't really prevent someone from copying the files over if they grab the shell executable and the additional libraries. It also seems more difficult to keep track of the specific build to go into different installer projects and prevents the purchased add-on scenario. To me, it seems best if the application's shell didn't need to reference the modules directly. Maybe, it could load the assemblies from a specific location but could somehow verify with a product key or elsewhere, that the user is supposed to have access to that module.

I'm interested if anyone has experience or insight on how to license modules or restrict access to modules to different users (versions) of the application. The basic application may be entirely free and require no license. Probably nothing can be foolproof, but I need to do my best to make it not easy for someone to get around the system. Another requirement is that I do not believe I can require my users will have internet access (in case there were some sort of licensing method which would require this). Of course, I'm not sure this is not limited to the discussion of .NET, Prism or Unity, but that is what I'm using for this project.

Signing each assembly with a strong key name can help me verify the modules are from a trusted source, but I'm not sure that would be helpful in the licensing. Maybe there is a product key system that can be used which would indicate which modules were allowed? Anyway, I'll stop there because I'm open-minded about any approach which solves this problem and I don't want to focus discussion along one specific idea or path.

Thanks for your help in advance.

Was it helpful?

Solution

I think this can be done using the following:

1)Extend the normal LifeTimeManagers you get in Unity. These are used to control when objects are disposed of and allow you to remove registrations from Unity

How to use LifeTimeManager to remove item from Unity:StackOverflow Answer

2)You'll need to build some sort of LifeTimeManager dictionary marrying a LifeTimeManager instance to a unity registration

3)Use a UnityContainerExtension to check the class being registered is "allowable". If it isn't allowable then resolve your LifeTimeManager dictionary, get the class lifetime manager and call "Remove" on it.

Here's a basic example of a UnityContainerExtension:

public class UnityNavigationTrackerExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Context.Registering += ContextRegistering;
            Context.RegisteringInstance += ContextRegisteringInstance;
        }

        private void ContextRegisteringInstance(object sender, RegisterInstanceEventArgs e)
        {
            var attributes =
                e.Instance.GetType().GetCustomAttributes(typeof (MenuItemAttribute), true) as MenuItemAttribute[];
            if (attributes != null)
                foreach (MenuItemAttribute attribute in attributes)
                {
                    RegisterMenuItemForView(e.RegisteredType, e.Instance.GetType(), attribute);
                }
        }
    }

What the unity container extension does is allow you to watch as classes register with unity. This means that you can interact with registrations as they happen.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top