How do I publish a Dynamics CRM4 plug-in with multiple assemblies? - plugins

My plugin DLL is really simple but references fifteen or so other DLLs. How do I register this?

Ways I know about are:
a) Put the other assemblies in the GAC (I think this is SDK preferred method). Will have to install on each client if needs to be taken online.
b) Use ILMerge to merge all of your assemblies into one assembly. You can deploy this to the database and have it used by your offline clients without a seperate install.

Related

How are NuGet components intended to be distributed to end users?

I'm still learning about NuGet and have a (hopefully not stupid) question: how are the components/assemblies in NuGet packages intended to be distributed to end users? The docs I've found are all about how NuGet packages get installed on developer systems, but nothing addresses how the resulting software is shipped/installed.
My best guess is that the developer using the package must decide how to get the components or assemblies to the end users, presumably by including them inside whatever installer the developer builds. The developer is also presumably responsible for any required registration (if side-by-side installation is not sufficient). Basically I'm guessing that NuGet and the concept of packages are out of the loop at this stage. Is that right?
They aren't intended for end users. NuGets purpose is to help developers manage their software dependencies. The developers still package and deploy their application and its dependencies the same way they always have.
This can be via an MSI installer, exe installer, ClickOnce or Windows Store installation.
NuGet adds the assemblies as references to your application's project. When you compile your application, you'll see all the assemblies you pulled in via NuGet in the output directory (typically bin\debug or bin\release).
The idea here, as Andy says, is that these assemblies are now part of your application just as if you had found the assembly and referenced it manually.
Basically I'm guessing that NuGet and the concept of packages are out of the loop at this stage. Is that right?
Yep. However you plan to ship your application binary is the same way you distribute the assemblies that were "installed" by the NuGet packages. You don't need to distribute the packages, just the assemblies that were referenced by your application.

Building customer based installation packages with install4j

I am developing an application which has customer specific configuration (2 text and 2 binary files). The use case supposes that customer downloads an installation package (I am going to use install4j) and install it on target platform (Mac or Windows). So all installation packages should be different for different customers.
I am considering 2 possible scenarios for implementation:
Generate new installation package per customer request on server side (cons: I need to have install4j for Linux, which is server platform)
Have a half-generated installation package and inject customer data somehow to the package by customer request (cons: I am not sure this is quite possible at all)
I never used install4j before and don't know how to implement 1 or 2. Their documentation is far from ideal. They doesn't have examples or consider cases like this, so any suggestion is very appreciated.
You cannot modify an installer after it has been built. The main reason is that it would break code signing. So you would need to generate a new installer for each configuration. If you deploy on Mac OS X and Windows, you need install4j Multi-Platform Edition which also works on Linux.
Alternatively, you could ask the user to provide credentials in the installer, then you could download the appropriate files on demand with "Download file" actions.

All in one installers or Core + Plugin Sub installers?

Build everything into one installable unit
Pros
One package to test and deploy to all environments
All plugins installed but possibly not registered for use in the config
Cons
Plugins may be in various states of the pipe how to deploy only good ones.
How to handle registering which plugins to deploy to which environment
Hard to change your mind might be a month between the dev build and the prod push
Build Core Installer (no plugins) + Sub installers (only the plugin)
Pros
Smaller footprint to prod less room for errors
Cons
Possibility of integration errors between plugins since they might be installed in various orders
How to rollback deployment when the previous deployment could be a strange assortment of core and sub installers. Need a way to track what the specific installation contains
How to reproduce errors in QA when QA has all plugins and prod may have a smaller possibly older subset.
These are my thoughts on the issue I have been strugling to have my cake and eat it too but I seem to be stuck with these two choices. Anybody else struggle with this issue and how did you resolve it? Any other pros and cons that I missed? So far I have chose the all or nothing approach but I am open to ideas.
Thanks in advance.
Build everything is easier to test and to deploy. You, at build time and by testing, guarantee all the plugins are compatible with each other. Depending on nature of the product, you can create bundles of plugins, which can be selected during installation.
Of course, there should an option to remove the plugins from the installation package which are not production-ready yet. But ensure QA gets what comes to customers or shareholders.
With separate packages approach, you have to implement dependency tracking and so forth. It is more flexible, which results in lots of possible combinations.
I'd choose the first option: one single package with everything and ability to fine-tune the selected features/plugins.
There's also one more option: combination of the two approaches above. Consider Eclipse project: it has a common platform and plugins. One can download a package with the set of plugins which are usually used in a particular environment. Other plugins can be installed later, if needed. So you combine your core with several logically connected plugins; other plugins could be added to the installation later.

Deploying that utilises .Net Reactive Extensions

Our application utilises Reactive Extensions (Rx). These are normally installed via the downloadable package from Microsoft. However, when we ship our application we supply copies of the dlls (namely System.CoreEx.dll and System.Reactive.dll). There appear to be two versions in the GAC v1.0.2787.0 and v1.0.2856.0. We are referencing a specific one and ship the appropriate versions.
However when the application launches it throws an error dialog which states the Rx Dlls must be installed in the GAC. It also requests the Dlls for the other version of Rx e.g. if you are referencing 1.0.2787 it will request 1.0.2856.0 and vice versa.
Has anyone got around this problem?
The Rx assemblies don't need to be installed into the GAC unless your application's assemblies are installed in the GAC. Does your application need to be installed in the GAC or can it run from the installation directory?
It also requests the Dlls for the other version of Rx e.g. if you are referencing 1.0.2787 it will request 1.0.2856.0 and vice versa
It's unlikely that it's actually requesting across versions of Rx. You might want to double/triple check that your solution (all projects) all reference the correct (and same) version of the Rx assemblies.

Is it possible to install an assembly into the GAC as some sort of 'linked assembly'?

I'm trying to deploy some sort of framework and therefore need to register some assemblies in the GAC.
The interesting part is:
These GAC assemblies should only be used by the framework developer, the client apps should not use these GAC assemblies but the ones in their local directories (the GAC assemblies could be of a different version, most likely higher).
I've already found and tried the app.config setting but it seems to be ignored by the client app (latest .NET runtime installed is 3.5).
Because you will be loading two different versions of a given dll in the memory you need to isolate them. common methods are;
Creating an AppDomain. You create two dll's. The first dll creates a new AppDomain from your code and then loads the second dll which is linked to those dependencies.
Use a service process. You create one dll and a service application. The dll starts the service application in a new process and connects using for e.g. remoting. The service application is linked to the components you need to bind to.