I have some generic interface
namespace SimpleLibrary
{
public interface IImported<T>
{
T Value { get; set; }
}
}
and its implementation in another .dll
namespace ImportedLibrary
{
[Export(typeof(IImported<>))]
public class ExportedEntry<T> : IImported<T>
{
public T Value { get; set; }
}
}
Then I make import into another class
namespace SimpleLibrary
{
public class MainEntry
{
[Import]
public IImported<string> Imported { get; set; }
public MainEntry()
{
try
{
var catalog = new DirectoryCatalog(Dir);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
Imported.Value = "Gomo Sapiens";
}
catch (CompositionException ex)
{
System.Diagnostics.Debugger.Launch();
}
catch (Exception ex)
{
System.Diagnostics.Debugger.Launch();
}
}
private string Dir
{
get
{
var dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "SimpleLibrary");
if (!Directory.Exists(dir))
{
dir = AppDomain.CurrentDomain.BaseDirectory;
}
return dir;
}
}
}
}
Then I create console application, put .dll
with class marked [Export]
inside bin\Debug
folder and run
static void Main(string[] args)
{
MainEntry me = new MainEntry();
Console.WriteLine(me.Imported.Value);
Console.ReadLine();
}
Everything works fine, console displays line "Gomo Sapiens".
However, when I create Wix Installer with some custom action that uses the same MainEntry
class and runs after InstallFinalize
, import doesn't work:
<Binary Id="ServerActions" SourceFile="path to CA.dll" />
<CustomAction Id="RunMainEntry" BinaryKey="ServerActions" DllEntry="RunMainEntry" Execute="immediate" Return="check" />
<InstallExecuteSequence>
<Custom Action='RunMainEntry' After='InstallFinalize'>NOT Installed AND NOT WIX_UPGRADE_DETECTED</Custom>
</InstallExecuteSequence>
and custom action code
public class CustomActions
{
[CustomAction]
public static ActionResult RunMainEntry(Session session)
{
MainEntry me = new MainEntry();
session.Log(me.Imported.Value);
return ActionResult.Success;
}
}
Custom action throws CompositionException
. Notice that my installer initially copies all files (.dll
and .exe
) inside Program Files(x86)\SimpleLibrary
, then calls custom action with MEF
composition. I want to highlight that at the moment of calling MainEntry
constructor all .dlls
do lie inside Program Files
folder and MEF
sees them but can't find what to import. And problem appears only with generics types, simple interfaces do import.
.NET Framework
version is 4.5
, C# 6.0
. CustomAction.config
:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Also tried to use MefContrib
, situation is the same.
Important thing is that when I run console app manually from Program Files(x86)
after installation complete everything again works fine.
So the question is how can I use MEF
from Wix's
custom actions and if I can't - why?