This is a migrated thread and some comments may be shown as answers.

Dynamically loading report assembly

2 Answers 322 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Nikita
Top achievements
Rank 1
Nikita asked on 17 Jan 2019, 01:57 PM

Hello. I've faced a problem trying to use HTML5 MVC Report viewer when using a .dll file loaded during runtime. I'm using a custom report resolver which creates TypeReportSource, sets a type name which I get from the loaded .dll  and then returns the created report source. However, the report viewer displays an error. (Stack trace below).

 

Is it possible to use reporting service with a dynamically loaded .dll like that? Or is it only possible if I reference the .dll in my project directly (when I do that, everything works, but this is obviously not a desired way for me)

stackTrace: "   в Telerik.Reporting.Processing.TypeReportDocumentResolver.Resolve(IProcessingContext context, TypeReportSource rs)<br>↵   в Telerik.Reporting.Processing.ReportDocumentResolver`1.Telerik.Reporting.Processing.IReportDocumentResolver.Resolve(IProcessingContext context, ReportSource rs)<br>↵   в Telerik.Reporting.Processing.ReportDocumentResolver.<>c__DisplayClass1.<Resolve>b__0(IReportDocumentResolver r)<br>↵   в Telerik.Reporting.Processing.ReportDocumentResolver.Bind[T](IProcessingContext context, ReportSource source, Func`2 func)<br>↵   в Telerik.Reporting.Processing.ReportDocumentResolver.Resolve(IProcessingContext context, ReportSource source)<br>↵   в Telerik.Reporting.Processing.ResolvedReportDocument.ResolveReportsRecursively(ReportSource rs, IProcessingContext context, IDictionary`2 parentRsParameters, Boolean parentShouldDispose, List`1 result, IReportDocument& definition, ResolvedReport& tocReport, ReportBookTocPosition& tocReportPosition)<br>↵   в Telerik.Reporting.Processing.ResolvedReportDocument.Create(ReportSource rs, IProcessingContext context)<br>↵   в Telerik.Reporting.Services.Engine.ReportEngine.GetParameters(String clientID, String report, Dictionary`2 parameterValues)<br>↵   в Telerik.Reporting.Services.WebApi.ReportsControllerBase.GetParameters(String clientID, ClientReportSource reportSource) в c:\temp\reporting\RBuild-18776\Reporting_Build\Source\Code\Telerik.Reporting.Services.WebApi\ReportsControllerBase.cs:строка 166<br>↵   в lambda_method(Closure , Object , Object[] )<br>↵   в System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_1.<GetExecutor>b__3(Object instance, Object[] methodParameters)<br>↵   в System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)<br>↵   в System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)<br>↵--- Конец трассировка стека из предыдущего расположения, где возникло исключение ---<br>↵   в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)<br>↵   в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)<br>↵   в System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()<br>↵--- Конец трассировка стека из предыдущего расположения, где возникло исключение ---<br>↵   в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)<br>↵   в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)<br>↵   в System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()<br>↵--- Конец трассировка стека из предыдущего расположения, где возникло исключение ---<br>↵   в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)<br>↵   в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)<br>↵   в System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()"

2 Answers, 1 is accepted

Sort by
0
Silviya
Telerik team
answered on 22 Jan 2019, 11:17 AM
Hi Nikita,

The TypeReportSource gets details which report to be processed based on the report's type. Then the reporting engine uses System.Reflection to create an instance of the report through its default parameterless constructor.

In order the report instance to be created, the type must be loaded and available before requesting the report. The assembly containing the report should be loaded in the application domain. Our suggestion is to load the assembly at a place where it can be globally accessible. For example in the Global.asax Application_Start load and resolve the assembly in the current domain: 
protected void Application_Start(object sender, EventArgs e)
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
 
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if (args.Name.Contains("ReportClassLibrary"))
    {
        return System.Reflection.Assembly.Load(System.IO.File.ReadAllBytes("[absolute_path]\\ReflectionDLL\\ReportClassLibrary.dll"));
    }
 
    return null;
}

Regards,
Silviya
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Nikita
Top achievements
Rank 1
answered on 22 Jan 2019, 12:30 PM
Silviya, thanks for the clarification!
Tags
General Discussions
Asked by
Nikita
Top achievements
Rank 1
Answers by
Silviya
Telerik team
Nikita
Top achievements
Rank 1
Share this question
or