MVC in a Core Library - c#

I built this project and it contained a simple MVC type structure to help with debugging information. Now the company wants to use it in other applications like a Library
The best way, I can describe it is
My Project Debugger Is a single controller with multiple end-points that render views (pretty basic), written in C#.
What I want is when another project wants to include my debugging, they would:
Add Debugger as a reference using NuGet.
Then in Start.cs the developer would use IApplicationBuilder.UseDebugger(IConfiguration, OtherInformation) or IServiceCollection.UseDebugger(IConfiguration, OtherInformation) and Debugger extension would do the rest like registering routes, building what it needs for dependency injection.
What I cannot figure out is what project type to use, I built it using .NET Core Web Application 3.1, but I do not think it is that. I also tried a .Net Standard class Library but I could not get a reference to controller to render views.
So to summarize, I want to convert part of my project to a library to allow for distribution to other applications.
A link to an example project would be helpful as well.

It sounds like you want a Razor Class Library.
Razor views, pages, controllers, page models, Razor components, View components, and data models can be built into a Razor class library (RCL). The RCL can be packaged and reused. Applications can include the RCL and override the views and pages it contains. When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence.
Edit: I just realised I answered a question about setting up a Razor Class Library last month, so that will give you a starting point, too.

Related

What works the same as cfinclude in C#?

In ColdFusion, I could create a page and reference it from other pages within the website by using the cfinclude tag.
I am using C# in Visual Studio 2010 - ASP.NET environment.
What is the equivalent of cfinclude in c#?
C# uses assemblies to separate code. The essence being that you add the other assembly as a reference to your second project, and then as musefun states, use the using keyword to "import" the relevant namespaces in to a particular .cs file.
Your question mentions pages. If you're using something like MVC with the razor syntax, you can use partial views to share html across multiple pages.
You can also compile razor views in to a dll and reference them that way (see RazorGenerator) - this enables you to share common views across multiple projects. Things such as jquery scripts and other common script files can also be shared by embedding them as resources within a shared library and writing some boilerplate code to redirect routes to virtual path providers - though that is perhaps beyond the scope of this question.
There is probably no equivalent to cfinclude in the .net framework. In ColdFusion, the included file has access to all the variables to the including file. For example
MainPage.cfm
<cfset myVariable = "Have a nice day">
<cfinclude template = "IncludedFile.cfm">
IncludedFile.cfm
<cfoutput>#myVariable#</cfoutput>
will display "Have a nice day".
I've only done a bit of .net stuff, but I have not seen anything where 1 file inherits variables from another.
That does not mean that you can't re-use code in .net. It just means that you have to do it another way.

MVC4 Shared Templates

I have a couple of MVC4 projects, and I'd like to make a set of display / editor templates that are reused across these projects. I'd like to create a common project that contains these templates, and reference it in the other projects.
So I have the views defined in my common project, along with some other utilities:
Common
- Models
- CommonMetadataAttribute.cs
- Views
- Shared
- EditorTemplates
- Decimal.cshtml
- Object.cshtml
- Password.cshtml
- String.cshtml
- Switch.cshtml
- ViewTemplates
- Object.cshtml
- Switch.cshtml
- Error.cstml
And in my client project's models I'd have
using MobileWeb.Common
public class MyViewModel
{
[UIHint("Switch")]
[CommonMetadata(Theme = "foo")]
public bool Enable { get; set; }
}
And in the client projects views I'd be able to generate my custom editors by simply calling:
#model MyViewModel
...
#Html.EditorFor(model => model.Enable)
Ideally, the client projects could override with their own templates, and it would just fall back to the common templates if no project-specific one was defined.
I've considered MvcContrib's portable areas, but I'm not sure if it will work since this is not really an area and I don't really know how to go about setting it up. Before I go down that road I'd like to know what is the preferred way of doing this?
Personally I have always been packaging templates as custom NuGets. You put your custom templates in a NuGet and when the user installs this NuGet in his project they are automatically added to the correct folders of his application. And automagically all the EditorFor/DisplayFor calls throughout the application start using your custom templates instead of the default ones.
This way you don't need to be writing some custom VirtualPathProviders (which break as soon as you precompile your application) in order to be retrieving Razor views embedded in third party assemblies and so on... Another advantage of using NuGets is that the user has your templates in his application and could easily modify them if he is not pleased with your work. And if he is really angry with you, all that he needs is to uninstall your NuGet in order to rollback his application to the default state.

Register Startup Script in MVC4

I realise this has been asked quite a few times for different languages / versions of .NET and MVC.
With MVC4, what is currently the accepted way to register a Javascript Startup Script? I want to fire a script off after the page has finished loading, is there a built in method or should I just be using jQuery to do it?
"Registering Startup Scripts" is a concept derived from ASP.Net WebForms, MVC has no such concept. To reference a "global" script file to be used on multiple pages add the script reference (<script></script>) to a Master View. To reference a script that is used on a single page/view reference it in the view itself.
MVC promotes Separation of Concerns enabling you to separate your view logic (scripts) from your domain/routing logic. Thus, mixing JavaScript, which is a client-side technology, with server-side code is mitigated if not eliminated.
ASP.Net 4 does come with Script Bundling & Minification abilities which would enable the bundling & minification of script references to better manage scenarios where an application has numerous script files.
http://www.beletsky.net/2012/04/new-in-aspnet-mvc4-bundling-and.html

Can MVC Views access all projects even though they aren't referenced by the project where the views are?

Ok, so I'm a bit confused as to what is going on with the following data.
We have the following Structure in our application:
Portal.Web - An MVC 3 Web App which basically contains all the
views, scripts, css and HTML helper extension methods
Portal.Core - A Class Library which is basically our Business Objects, we have all of our models contained within this project.
Portal.Data - Another Class Library which contains our NHibernate config and our DTO classes.
Here's our usage: In the controller we call the model located in Portal.Core, which populates by calling Portal.Data, so basically Web can never see data.
Here's the catch: In the controller, say for example I try and instantiate a new DTO object called Client like so:
var client = new Client();
It won't work, which is expected it has no idea what Client is and even specifying a using won't cut it. That's fine.
BUT if I try and do that exact same line in the View, Resharper adds the using to the view and then no complaints, the project runs and we can use DTO classes in our views.
So the question is, why is this? I'm trying to stop our juniors from using DTO classes in Views, so I've purposely removed the reference to the Data project in Web, but they can still use the classes. Can someone shed some light?
I ran the same test with ASPX and Razor views. Referencing Client in ASPX views fails however in Razor views they work. The views are compiled on the fly when you request the application, so I had a look at some folders in "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\portal.web" and from cmdline files references to the assembly is explicitly added when the view is compiled.
It seems the process that compiles razor views adds references to all the assemblies in the bin folder. However, looking at the source of ASP.NET MVC, I cannot confirm this.
So, the only conclusion I can come to is that it is a side effect of using the Razor View Engine.
That said, you may want to scan the web.config to see if it was included using the assemblies element.

How to use Plugin Architecture in ASP.NET?

I really like the plugin architecture of WinForms and I want to use a plugin architecture in Asp.net.
I've searched for plugins architecture in asp.net and I've found asp.net MVC samples, but I want to use classic asp.net project not MVC.
Does anyone know of any resources for patterns using classic asp.net, not MVC?
You can roll your own.
A plugin architecture needs a few not-so-complex parts:
A way to identify where the plugin dll is located
An interface or base class definition that all plugins must adhere to. This is the most important one. It decides what functionality your plugin can expose and how deeply it can integrate with your app
A place (in time) when your plugin gets loaded and executed. (ie, does the plugin execute for each web page request? Or for requests matching a certain name? Or does the page manually invoke plugins?)
Once you have this figured out, instantiating an instance of a plugin is simple. It works the same regardless of whether you're running in a web app or on the client:
System.Reflection.Assembly a = System.Reflection.Assembly.LoadFrom(plugin_path);
t = a.GetType("IPlugin");
IPlugin plugin = (IPlugin)Activator.CreateInstance(t);
then, you can use plugin.DoSomething() to actually invoke functionality from the plugin. (Whether it is to render part of the html or save to a DB or whatever)
Look at Managed Extensibility Framework

Categories

Resources