ArgumentNullException when using Assembly.LoadFrom

Oct 12, 2011 at 10:26 AM

I have this error as well.

Maybe someone knows the solution?

Oct 12, 2011 at 1:12 PM
Edited Oct 12, 2011 at 1:15 PM

 

I'm trying to use Razor.Engine for parsing the e-mail templates. All works fine unless I'm trying to load assembly dynamically.

The Engine (this is my class which has only one method Parse):

 

public string Parse(string template, dynamic model)
        {
            return Razor.Parse(template, model);
        }
 

If my test project has reference to library with Razor.Parse method everything works fime:

 

       
 [TestMethod]
        public void Engine_should_properly_parse_the_string()
        {
            const string template = "Hello @Model.PartId engine test";

            var model = new EmailModel { PartId = 123 };

            var engine = new Engine();
            var result = engine.Parse(template, model);

            Assert.AreEqual("Hello 123 engine test", result);
        }

But if i'm trying next test in new test project without direct reference to library:

[TestMethod]
        public void TestMethod1()
        {
            const string template = "Hello @Model.PartId engine test";

            var model = new my { PartId = 123 };

            var assembly = Assembly.LoadFrom(@"..\..\..\EmailNotifier\bin\Debug\EmailNotifier.dll");
            dynamic builder = assembly.CreateInstance("EmailNotifier.Notifier.Engine");
            var result = builder.Parse(template, model);

            Assert.AreEqual("Hello 123 engine test", result);
        }

I have the next error:

Test method TestProject1.UnitTest1.TestMethod1 threw exception: 
System.ArgumentNullException: Value cannot be null.
Parameter name: type
at RazorEngine.Templating.DefaultActivator.CreateInstance(Type type)
at RazorEngine.Templating.TemplateService.CreateTemplate(String templateType modelType)
at RazorEngine.Templating.TemplateService.GetTemplate(String templateType modelTypeString name)
at RazorEngine.Templating.TemplateService.Parse(String templateT modelString name)
at RazorEngine.Razor.Parse(String templateT modelString name)
at System.Dynamic.UpdateDelegates.UpdateAndExecute3<T0,T1,T2,TRet>(CallSite siteT0 arg0T1 arg1T2 arg2)
at Notifier.Engine.Parse(String templateObject model) in Engine.cs: line 48
at System.Dynamic.UpdateDelegates.UpdateAndExecute3<T0,T1,T2,TRet>(CallSite siteT0 arg0T1 arg1T2 arg2)
at TestProject1.UnitTest1.TestMethod1() in UnitTest1.cs: line 27
I've found that Razor tries to run RazorEngine.Templating.DefaultActivator.CreateInstance(Type type) where the type equals null.

it looks like Razor doesn't want to do the runtime compilation :(

Maybe i have to do some initialization of the Razor classes?

Maybe someone has a solution of this problem?
Coordinator
Oct 12, 2011 at 4:44 PM

I'll add this to my list of things to check before I push v3 LIVE


Oct 12, 2011 at 4:51 PM

Thanks

Nov 25, 2011 at 12:37 AM

I had a similar issue and have managed to work around it.  My setup is as follows:

 - WCF Service that loads assemblies dynamically (using Assembly.LoadFrom) from a different location to the service (basic plugins infrastructure)

 - Plugin Assemblies that execute razorengine templates

1. In the plugin assembly I have set the RazorEngine and System.Web.Razor CopyLocal to false. 

2. I have copied the System.Web.Razor and RazorEngine assemblies to WCF bin directory.

3. In the plugin I use a dynamic class for the model.  The line is as follows:

var str = Razor.Parse(Encoding.UTF8.GetString(bytes), new { Symbol = model.Symbol })

If I use the strongly typed model I get the same error as posted.  Using this method outlined gets around it.  Note that you must ensure that the razor assemblies are in the host app domain bin path.  If they are outside of it you will get these errors.

Hope this helps.

Thanks

 

Craig.

Nov 29, 2011 at 6:36 AM

Thanks, craig_c for the workaround!

But I hope it will be fixed in the new release.

Jan 8, 2013 at 12:24 PM

All, I am fac ing the same issue. Did you find a solution?

 

AntarisZX,

Did you have a version with a fix?

Jan 10, 2013 at 5:42 PM

Here's what fixed this problem for me. I had to help the runtime load the missing assemblies, so I used the AssemblyResolve event of the current AppDomain and manually loaded the missed assemblies:

        public string RenderText<T>(string templateText, T data)
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
            try {
                return Razor.Parse(templateText, data);
            } finally {
                AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
            }
        }

        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
            return Assembly.Load(args.Name);
        }

For me this error was happening in a custom MSBuild task that I wrote using RazorEngine to create a report.

 

Jan 21, 2013 at 10:20 PM

Is this problem officially fixed? or do we have go with the work around for now?

Feb 28, 2013 at 10:46 AM
Edited Feb 28, 2013 at 10:46 AM
I debugged the code and found that the issue is the RazorEngine is trying to load itself when compile the template but can't find that in the loaded assemblies. So I fixed this problem by install RazorEngine dll in the GAC using .NET Framewok 4 tool with the following command.


Install RazorEngine to GAC 4.0

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\gacutil" /f /i RazorEngine.dll