trailmax
trailmax

Reputation: 35116

Different resource files for different client deployments

I'm developing a WinForms application for 2 clients. The difference between the clients are only in branding: ClientA gets LogoA.png. ClientB gets LogoB.png. I need to ship the application to them as in installer and as zip file with all executables.

I'm thinking putting the images in different resource files and compile them as satellite assemblies and on the build server, when I produce zip-file and installer, I include only ResourceA for ClientA and ResourceB for ClientB. That is the plan, but I've never done this before.

The documentation says that resource files should be identified by language and culture codes. Both of my clients will run their machines in English (en-GB or en-US). I can ignore the recommendation and call the resources by the name of clients. But would they be picked up by the application? (taking there is only one resource file and machine culture does not match the resource culture code).

Is there a better solution for that?

p.s. I know about compiler directives, but it is making code hacky and dirty. Possibly, in the future, clients will have different text on the screens and that is the perfect case for the resources.

Upvotes: 0

Views: 807

Answers (2)

Alexandr Mihalciuc
Alexandr Mihalciuc

Reputation: 2577

You can create a separate build configuration for each company. Then you can change the .csproj file to have msbuild tasks which will replace default resource file with chosen company resources, here is example how to check current configuration in msbuild.

<PropertyGroup Condition="'$(Configuration)' == 'CompanyABuild'">
  //set resource to point to company A
</PropertGroup>
<PropertyGroup Condition="'$(Configuration)' == 'CompanyBBuild'">
    //set resource to point to company B
</PropertGroup>

Upvotes: 1

Alexandr Mihalciuc
Alexandr Mihalciuc

Reputation: 2577

You can add to separate resource file one for clientA another one for clientB (ClientA.resx, Clinetb.resx). Then add a config entry in your app.config file with the name of the resource to use. Then you need to create a wrapper class which will provide you resources depending on the config value, you need to use dynamic objects and resource managers here is a sample code:

 class Program
    {
        static void Main(string[] args)
        {
            var res = new CompanyAResource();

            var companyResources = new global::System.Resources.ResourceManager("ConsoleApplication1.CompanyAResource", typeof(CompanyAResource).Assembly);

            dynamic resources = new DynamicResources(companyResources);

            string name = resources.CompanyName;

            Console.WriteLine(name);

        }     
    }

    public class DynamicResources : System.Dynamic.DynamicObject
    {
        private ResourceManager resources;

        public DynamicResources(ResourceManager resources)
        {
            this.resources = resources;
        }      

        public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
        {
            result = this.resources.GetString(binder.Name);
            return true;
        }      
    }

Upvotes: 1

Related Questions