Dynamically Loaded Assemblies - MVC & WCF act differently
I am dynamically loading assemblies from a database table of assembly names, which insert rules into a rules engine. The idea is we can extend functionality by developing new rules without having to recompile and deploy the whole suite.
There's a MVC web application, and a WCF desktop application that share a great deal of the code, including the RulesRunner class I'm describing here.
This code is in the constructor of the RulesRunner class
rules = rulesEngineRepository.GetRules(x => x.Enabled);
foreach (var rule in rules)
var ruleAssembly = Assembly.LoadFrom($"rule.AssemblyName.dll");
var installerType = ruleAssembly.GetType("RulesEngine.Rules.RulesInstaller");
var installer = Activator.CreateInstance(installerType) as IWindsorInstaller;
container.Install(installer);
The RulesRunner class is not dynamically loaded, it's compiled in as a normal reference in both MVC and WCF code.
In the WCF case, this all works exactly as intended. The assembly is loaded, an instance is created and when the rules engine fires elsewhere it uses the rules loaded in this way perfectly.
In the MVC web application, this code returns a null from the Activator.CreateInstance line and so fails further along when it's called. I cannot for the life of me work out what's going on differently here.
If I inspect the variables after the call to container.Install(installer) I can see the variable installer reports "'installer' threw an exception of type 'System.IO.FileNotFoundException'".
But but but but... the installerType has all the correct information and value. It's like it's found the DLL to execute the LoadFrom, but then can't find it again when it tries to instantiate it two lines of code further along.
.net wcf model-view-controller reflection
add a comment |
I am dynamically loading assemblies from a database table of assembly names, which insert rules into a rules engine. The idea is we can extend functionality by developing new rules without having to recompile and deploy the whole suite.
There's a MVC web application, and a WCF desktop application that share a great deal of the code, including the RulesRunner class I'm describing here.
This code is in the constructor of the RulesRunner class
rules = rulesEngineRepository.GetRules(x => x.Enabled);
foreach (var rule in rules)
var ruleAssembly = Assembly.LoadFrom($"rule.AssemblyName.dll");
var installerType = ruleAssembly.GetType("RulesEngine.Rules.RulesInstaller");
var installer = Activator.CreateInstance(installerType) as IWindsorInstaller;
container.Install(installer);
The RulesRunner class is not dynamically loaded, it's compiled in as a normal reference in both MVC and WCF code.
In the WCF case, this all works exactly as intended. The assembly is loaded, an instance is created and when the rules engine fires elsewhere it uses the rules loaded in this way perfectly.
In the MVC web application, this code returns a null from the Activator.CreateInstance line and so fails further along when it's called. I cannot for the life of me work out what's going on differently here.
If I inspect the variables after the call to container.Install(installer) I can see the variable installer reports "'installer' threw an exception of type 'System.IO.FileNotFoundException'".
But but but but... the installerType has all the correct information and value. It's like it's found the DLL to execute the LoadFrom, but then can't find it again when it tries to instantiate it two lines of code further along.
.net wcf model-view-controller reflection
In my experience assembly resolution and loading can be a hussle, you can probably skip all that if its possible for your use-case to use theAssembly.Load(byte)
overload.
– thehennyy
Nov 12 at 13:09
@thehennyy if I switch to use var ruleAssembly = Assembly.Load(File.ReadAllBytes($"rule.AssemblyName.dll")); then the exact same thing happens.
– IntoNET
Nov 12 at 13:13
Then some code in the assembly you load references another assembly that is not loaded yet and probably can not be found. You could try to register an eventhandler for assembly/type-load events and debug from there. Did you make sure both projects are compiled against the exact same assemblies (not recompiled in the meantime)?
– thehennyy
Nov 12 at 13:36
add a comment |
I am dynamically loading assemblies from a database table of assembly names, which insert rules into a rules engine. The idea is we can extend functionality by developing new rules without having to recompile and deploy the whole suite.
There's a MVC web application, and a WCF desktop application that share a great deal of the code, including the RulesRunner class I'm describing here.
This code is in the constructor of the RulesRunner class
rules = rulesEngineRepository.GetRules(x => x.Enabled);
foreach (var rule in rules)
var ruleAssembly = Assembly.LoadFrom($"rule.AssemblyName.dll");
var installerType = ruleAssembly.GetType("RulesEngine.Rules.RulesInstaller");
var installer = Activator.CreateInstance(installerType) as IWindsorInstaller;
container.Install(installer);
The RulesRunner class is not dynamically loaded, it's compiled in as a normal reference in both MVC and WCF code.
In the WCF case, this all works exactly as intended. The assembly is loaded, an instance is created and when the rules engine fires elsewhere it uses the rules loaded in this way perfectly.
In the MVC web application, this code returns a null from the Activator.CreateInstance line and so fails further along when it's called. I cannot for the life of me work out what's going on differently here.
If I inspect the variables after the call to container.Install(installer) I can see the variable installer reports "'installer' threw an exception of type 'System.IO.FileNotFoundException'".
But but but but... the installerType has all the correct information and value. It's like it's found the DLL to execute the LoadFrom, but then can't find it again when it tries to instantiate it two lines of code further along.
.net wcf model-view-controller reflection
I am dynamically loading assemblies from a database table of assembly names, which insert rules into a rules engine. The idea is we can extend functionality by developing new rules without having to recompile and deploy the whole suite.
There's a MVC web application, and a WCF desktop application that share a great deal of the code, including the RulesRunner class I'm describing here.
This code is in the constructor of the RulesRunner class
rules = rulesEngineRepository.GetRules(x => x.Enabled);
foreach (var rule in rules)
var ruleAssembly = Assembly.LoadFrom($"rule.AssemblyName.dll");
var installerType = ruleAssembly.GetType("RulesEngine.Rules.RulesInstaller");
var installer = Activator.CreateInstance(installerType) as IWindsorInstaller;
container.Install(installer);
The RulesRunner class is not dynamically loaded, it's compiled in as a normal reference in both MVC and WCF code.
In the WCF case, this all works exactly as intended. The assembly is loaded, an instance is created and when the rules engine fires elsewhere it uses the rules loaded in this way perfectly.
In the MVC web application, this code returns a null from the Activator.CreateInstance line and so fails further along when it's called. I cannot for the life of me work out what's going on differently here.
If I inspect the variables after the call to container.Install(installer) I can see the variable installer reports "'installer' threw an exception of type 'System.IO.FileNotFoundException'".
But but but but... the installerType has all the correct information and value. It's like it's found the DLL to execute the LoadFrom, but then can't find it again when it tries to instantiate it two lines of code further along.
.net wcf model-view-controller reflection
.net wcf model-view-controller reflection
asked Nov 12 at 13:00
IntoNET
301112
301112
In my experience assembly resolution and loading can be a hussle, you can probably skip all that if its possible for your use-case to use theAssembly.Load(byte)
overload.
– thehennyy
Nov 12 at 13:09
@thehennyy if I switch to use var ruleAssembly = Assembly.Load(File.ReadAllBytes($"rule.AssemblyName.dll")); then the exact same thing happens.
– IntoNET
Nov 12 at 13:13
Then some code in the assembly you load references another assembly that is not loaded yet and probably can not be found. You could try to register an eventhandler for assembly/type-load events and debug from there. Did you make sure both projects are compiled against the exact same assemblies (not recompiled in the meantime)?
– thehennyy
Nov 12 at 13:36
add a comment |
In my experience assembly resolution and loading can be a hussle, you can probably skip all that if its possible for your use-case to use theAssembly.Load(byte)
overload.
– thehennyy
Nov 12 at 13:09
@thehennyy if I switch to use var ruleAssembly = Assembly.Load(File.ReadAllBytes($"rule.AssemblyName.dll")); then the exact same thing happens.
– IntoNET
Nov 12 at 13:13
Then some code in the assembly you load references another assembly that is not loaded yet and probably can not be found. You could try to register an eventhandler for assembly/type-load events and debug from there. Did you make sure both projects are compiled against the exact same assemblies (not recompiled in the meantime)?
– thehennyy
Nov 12 at 13:36
In my experience assembly resolution and loading can be a hussle, you can probably skip all that if its possible for your use-case to use the
Assembly.Load(byte)
overload.– thehennyy
Nov 12 at 13:09
In my experience assembly resolution and loading can be a hussle, you can probably skip all that if its possible for your use-case to use the
Assembly.Load(byte)
overload.– thehennyy
Nov 12 at 13:09
@thehennyy if I switch to use var ruleAssembly = Assembly.Load(File.ReadAllBytes($"rule.AssemblyName.dll")); then the exact same thing happens.
– IntoNET
Nov 12 at 13:13
@thehennyy if I switch to use var ruleAssembly = Assembly.Load(File.ReadAllBytes($"rule.AssemblyName.dll")); then the exact same thing happens.
– IntoNET
Nov 12 at 13:13
Then some code in the assembly you load references another assembly that is not loaded yet and probably can not be found. You could try to register an eventhandler for assembly/type-load events and debug from there. Did you make sure both projects are compiled against the exact same assemblies (not recompiled in the meantime)?
– thehennyy
Nov 12 at 13:36
Then some code in the assembly you load references another assembly that is not loaded yet and probably can not be found. You could try to register an eventhandler for assembly/type-load events and debug from there. Did you make sure both projects are compiled against the exact same assemblies (not recompiled in the meantime)?
– thehennyy
Nov 12 at 13:36
add a comment |
1 Answer
1
active
oldest
votes
The fix to this was quite simple in the end:
var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");
The switch from LoadFrom() to Load() was all it needed. I believe this is to do with the context that the assembly is loaded into.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262721%2fdynamically-loaded-assemblies-mvc-wcf-act-differently%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The fix to this was quite simple in the end:
var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");
The switch from LoadFrom() to Load() was all it needed. I believe this is to do with the context that the assembly is loaded into.
add a comment |
The fix to this was quite simple in the end:
var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");
The switch from LoadFrom() to Load() was all it needed. I believe this is to do with the context that the assembly is loaded into.
add a comment |
The fix to this was quite simple in the end:
var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");
The switch from LoadFrom() to Load() was all it needed. I believe this is to do with the context that the assembly is loaded into.
The fix to this was quite simple in the end:
var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");
The switch from LoadFrom() to Load() was all it needed. I believe this is to do with the context that the assembly is loaded into.
answered Nov 13 at 11:19
IntoNET
301112
301112
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262721%2fdynamically-loaded-assemblies-mvc-wcf-act-differently%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
In my experience assembly resolution and loading can be a hussle, you can probably skip all that if its possible for your use-case to use the
Assembly.Load(byte)
overload.– thehennyy
Nov 12 at 13:09
@thehennyy if I switch to use var ruleAssembly = Assembly.Load(File.ReadAllBytes($"rule.AssemblyName.dll")); then the exact same thing happens.
– IntoNET
Nov 12 at 13:13
Then some code in the assembly you load references another assembly that is not loaded yet and probably can not be found. You could try to register an eventhandler for assembly/type-load events and debug from there. Did you make sure both projects are compiled against the exact same assemblies (not recompiled in the meantime)?
– thehennyy
Nov 12 at 13:36