Dynamically Loaded Assemblies - MVC & WCF act differently










0














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.










share|improve this question





















  • 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















0














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.










share|improve this question





















  • 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













0












0








0







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.










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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
















  • 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















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












1 Answer
1






active

oldest

votes


















0














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.






share|improve this answer




















    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
    );



    );













    draft saved

    draft discarded


















    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









    0














    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.






    share|improve this answer

























      0














      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.






      share|improve this answer























        0












        0








        0






        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.






        share|improve this answer












        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 at 11:19









        IntoNET

        301112




        301112



























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            Barbados

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3