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.
Related
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.
I am trying to build a new MVC Project. The thought is I will have a parent domain, and I will be hosting multiple sub products at different sub domains.
[ For Users it will be totally different products.. like: life.insurance.com and general.insurance.com].. and it is also possible that two different teams work on these two child products and they may have different Release Date.
Main thing is, I want to change my Web Project Layer. The Domain Layer, DAL Layer, etc will be common. I was searching for some best Industry Practices in MVC.
Thoughts that I have in Mind:
Create different MVC Areas in Web Project. But what if I want to send product A code to Production but not the Product 2 Code. [How to Resolve this]
Use different Web Projects and change the dll only at Production.
Please suggest. or any New way to handle this scenario?
Under Main Project solution, Create Separate MVC projects for each of the subdomains.
You can create multiple projects for DAL, DomainLayer, Crosscutting, DTOs, UI, Test etc. You can extend it as much as you need and you can find many sample architectures in different complexities. Considering your specific questions, you can route requests using Area as you pointed. In addition, you can implement Areas in different projects which enable you extend your solution without modifying the web project. However; you need to take into consideration that once you add DLL references to your web project, you cannot directly change specific DLLs without rebuilding the whole web project. In order to achive that, you need to resolve your plugin assemblies in runtime. So, you can use Assembly.Load that will help you load specific DLLs anytime you wish.
I am working on a massive ERP on student lifecycle management.
My platform is ASP.NET Web Forms.
Originally, I created my project using the N-tier format, where I had separate tiers for the data access, business logic, and the view.
I had to create different types of view based on different stakeholders, and so my project had different folders to hold the views of a particular stakeholder.
I had folders to hold my data access and business logic as well.
Overall, my project structure was like this:
Project
--BusinessLogic
--class files
--DataAccess
--class files
--Student
--html pages
--Principal
--html pages
--AccountsDept
--html pages
--Teacher
--html pages
--LoginSystem
--html pages
Now, I want to breakdown this structure, because I want to host my student and teacher portals on different servers. But the student and teacher portal will use the same data access layer and the same business logic layer, so I want to make any code changes to these layers from one single page.
I am thinking of this structure
Project 1
--BusinessLogic
--dll files
--DataAccess
--dll files
Student Portal
--Student
--html pages
--LoginSystem
--html pages
Teacher Portal
--Teacher
--html pages
--LoginSystem
--html pages
My view related projects will reference the dlls created from publishing Project 1.
Previously, when I published my single project, I saw that all my c# class files compiled into a single dll files. I think it is possible to reference this dll file in my view related project.
The problem is that, I have a intuition / hunch that this might be possible. But I am not even sure. I do not know whether this is the right way or not.
I am also not wanting to use multiple projects inside a single solution. I want to keep everything separate.
You can think of DLLs like plugins, which can be used across any compatible application as references(this is what you see under References section of your project anyway). The great thing is that DLL can be created by anyone - either Microsoft, third-party company or even yourself, there is no limitations.
Reusing your own components is completely fine and I strongly encourage you to do this. Just remember that if you have some layers, which you want to separate, create additional project as Class Library. Of course it is possible to reference DLLs created as a result of building your web project, but this can cause either errors or unexpected application behavior, since Class Library is designed in a way that it only exposes its interface, without triggering any application life cycle events.
I'm kind of new to Silverlight and I have a solution which has one web project (webApp) that provides remote services and two client applications (client-1 and client-2) that uses these services.
I have created a complex user control in client-1 that view/edit an object retrieved from webApp and I want to re-use this control in client-2.
The problem is, when you reference the service from the client apps, the types are "locally-typed". For example, MyClass defined in the webApp becomes client-1.MyClass in client-1 app. Using exactly the same object (reference) in client-2 app, it is now of type client-2.MyClass
If I create a library to host my control, I will have to add a reference to the web services and I will have a third type, lib.MyClass. We all know that client-1.MyClass, client-2.MyClass and lib.MyClass are all exactly the same class that was generated from web.MyClass but I can't find a way around this problem.
I'm currently looking at sharing the source code of the user control in each client application and having pre-processor defines in each project so I can do this in my user control code file:
#if CLIENT-1
using Client-1.WebAppServiceReference
#end if
#if CLIENT-2
using Client-2.WebAppServiceReference
#end if
Then the method that uses the type MyClass are using the correct "local-type" in each client app. But I'm having problem since there is no pre-processor functionality in the xaml and there is a reference to the application's namespace there that I need to be conditional.
There's got a be an easier way of re-using controls accross silverlight projects, no?? There is no way I'm going to have two copies of the source files for this control, on in each project!!
Thanks!
There are a couple of options that allow you to use shared entity classes across Silverlight projects/WCF service proxies.
Use an RIA class library
Use a portable class library
If you create your DataContract classes with either of the above, and then reference the library from both your WCF and Silverlight client projects, then the auto-generated code will use a reference to those shared classes (rather than the locally auto-generated classes). This should allow you to re-use your Silverlight UserControls between projects.
The difference between the two approaches is this. If you use the first approach (RIA project), then when you create files named "SomeEntityClass.shared.cs", the ".shared" tells Visual Studio to place a copy of the file in a mirror Silverlight project. The second approach (PCL) is a newer approach -- it allows you to create class libraries that are capable of targeting multiple platforms (.Net, Silverlight, Windows Phone, ...), with a reduced set of core .NET libraries.
I suggest you to dissociate the XAML and graphical stuff from any of Business logics and the like. MVVM is a very good pattern to follow.
After that, you can reference your UserControl from second project with the very useful functionality of Visual Studio "Add as Link"
Here how you can do it :
For the underlying business, you can make it available for both project, and linking these 2 with it.
Hope it helps
We are in the process of moving our application to .NET. One of the main goals is to allow modifications to the application, per client, but not to the source code. We resolved this in the core framework by programming to interfaces and using a Dependency Resolver (having an option to override the base registration) and MEF.
Now when it comes to views (the UI the client sees) the templates seem static and if the client wants to add a new field to the screen it seems they would need to modify the view itself.
The only two things that I can think of is modifying the search path of viewengine. This would allow a copy of the base and changes to it would be picked up. Not really liking this as it's a copy of the code.
The other way, what we are doing now, is that we create a class that is a container to other objects that output HTML. Basically we have a PageObject, LabelObject, InputObject..ect that we can call render on and output HTML. Since they are classes we can use the same methodology as for the rest of the application of giving slice in points. Going this route we really are not using the viewengine for rendering but just for combining all the partial views. Seems kind of clunky.
Is there a different way to accomplish this goal or a different viewengine that I can use to meet the goal of allowing customization for clients without touching the base view? I know HTML is not an object but seems there has to be something in between ASP.NET WebForms and ASP.NET MVC when dealing with HTML and allowing for customizations.
I would create a strongly typed partial view or template (DisplayTemplate or EditorTemplate based on requirements) whose #model is a collection of things that are rendered as inputs and labels. Allow the client to add/remove items from the persisted collection (i.e. in a database) and your problem is solved using the built in ViewEngine.