Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference to assembly in mvc at runtime

Tags:

In my Asp.Net MVC application, i have some view file (.cshtml) which has reference to an external library which it will be loaded at runtime. so after app started, i load the assembly by Assembly.Load and i register the controllers by my own custom ControllerFactory and every thing is ok.

But, in some views which has references to the dynamically loaded assembly, throws the :

Compiler Error Message: CS0234: The type or namespace name 'MyDynamicNamespace' does not exist in the namespace 'MyApp' (are you missing an assembly reference?)

exception that tells the razor compiler cannot resolve the related assembly.

My question is that, is there a way to register the assembly at runtime, to able the razor compiler can access to it and resolve it?

Notice that i can't use BuildManager.AddReferencedAssembly method because my assembly have to be loaded after app start, and the BuildManager does not support it.

like image 990
Ali Adlavaran Avatar asked Jun 28 '15 06:06

Ali Adlavaran


People also ask

Which of the following helps in finding the methods of an assembly file at runtime?

The term probing is often used when describing how the runtime locates assemblies; it refers to the set of heuristics used to locate the assembly based on its name and culture. You can view binding information in the log file using the Assembly Binding Log Viewer (Fuslogvw.exe), which is included in the Windows SDK.

How do I reference assemblies in C#?

In the Project Designer, click the References tab. Click the Add button to open the Add Reference dialog box. In the Add Reference dialog box, select the tab indicating the type of component you want to reference. Select the components you want to reference, and then click OK.

How do I add a reference to .NET assembly?

To use the Add Reference window In the AOT, right-click References, and then click Add reference. The Add reference window opens. Review the top list to locate the assembly that contains the control you want to use. Click the assembly name and then click the Select button.


1 Answers

1) I wouldn't recommend having your views directly use external references or dynamically loaded external references. Abstract this by having your view interact with a controller. Make your controller feed a data object to your view that is known at build time by your application (in other words, an object known to your web application at build time). This is to completely isolate (abstract) plugin specific business from your view. Then make your controller interact with the "plugin".

2) I don't know how your "custom factory" works but nowadays we don't really build any "custom factories" anymore. Instead we leverage dependency injection containers such as Microsoft Unity(or Ninject, or Castle Windsor or etc..). Creating "custom factories" is very old fashioned and you're basically reinventing the wheel that has been solved with dependency injection.

3) As far as dynamically loading external assemblies, I don't know if you have it right but here's a link:

Dynamically load a type from an external assembly

4) Typically, a plugin design exposes interfaces that are known to your main web application at build time. What the plugin design hides is the implementation which can change from one plugin to another. The important thing is that each plugin implements the same public interfaces, those that are expected by your main web app. Usually, you will have those interfaces in a separate "Common" project that is referenced by both, your main web application and your plugin that implements those interfaces. Therefore, from your main web app, you will know what the public interfaces of your plugins are, you can dynamically load the external assembly and use C# reflection to find the classes that implements those interfaces and load them into your dependency injection container. Likewise, anyone who will want to develop of a plugin for your web app will have to implement the interfaces that are defined in your "Common" project.

Note: "Common" is just a random name I gave to the project. You can name it "PluginInterface" or whatever you want.

After that, having your controller grab whatever it needs from the dependency injection container is trivial.

Note: Your plugin interfaces will probably have input and output entities. These entities are shared between your main web app and your plugin. In such case, since these entities are part of your interfaces they need to be in the "Common" project. You may be tempted to have your controller return those entities directly to your view but then you won't have a perfect abstraction between your view and your plugin. Not having perfect abstractions is for another discussion.

Hope it helps!

like image 158
TchiYuan Avatar answered Oct 08 '22 00:10

TchiYuan