Comments (9)
I'm still of the opinion that any developer who is using their own AppInitialize is sufficiently capable of fixing a conflict, and also I like that the current approach doesn't require require referencing WebActivatorEx (which I've had versioning issues with before, when referenced packages have required specific versions). On the other hand, App_code compiles weirdly.
@mycroes Your approach makes the following changes right?
- + Don't use app_code so it's compiled at build time, not runtime
- + Don't use AppInitialize so no conflict
- - New reference on WebActivatorEx
I think I'm happy with accepting that.
On the self registration: I don't think it's a good idea to have the assembly providing the resources self register from inside compiled code, too magic IMO, and has scope for double registrations. That said, I'm not sure that the current out-of-the-box approach is too good either though, as it potentially makes every embedded resource in your system callable... Persuade me if you think it's really important!
from embeddedresourcevirtualpathprovider.
Yes those would be the changes. About the registration: I can see two useful approaches:
- Startup project references ERVPP and tells which assemblies to expose (current)
- Resource hosting projects expose ERVPP with their own resources
Let's assume someone wants to host resources because it's a shared project (I can't really figure any other case why one would want to do this).
The result of option 1 is that you'd have only one VirtualPathProvider for ERVPP that exposes all the (configured) resources in the application. It requires the shared projects to just embed the resources, nothing else. The startup project needs the App_(Code|Start) class to load ERVPP and it might need configuration/customization (I'm not sure what happens when customizing and updating the package, will NuGet prompt or overwrite?) if you don't want to expose all referenced assemblies.
With option 2 the control is moved to the individual projects, and every resource hosting project will need to reference ERVPP and register the VirtualPathProvider. This also means that with n assemblies with resources you'll have n VirtualPathProviders which means that virtual path resolution becomes an O(n) process, contrary to the case where there is only one VirtualPathProvider and the lookup in ERVPP is near O(1) (Dictionary key lookup complexity according to MS).
Something went wrong, I guess I just persuaded myself to go for option 1.
from embeddedresourcevirtualpathprovider.
I think it's fine as it is:
Typically, a VirtualPathProvider instance is registered in an AppInitialize method defined in the App_Code directory,
https://msdn.microsoft.com/en-us/library/bhesyfec.aspx?f=255&MSPPError=-2147217396
from embeddedresourcevirtualpathprovider.
Apologies if there is a bug, if i'ts that the docs are wrong/incomplete I'll happily accept a PR*.
*actually docs are my fave type of PR ever.
from embeddedresourcevirtualpathprovider.
I guess MS is always right but think about RouteConfig, BundleConfig, etc. are registered in App_Start. And maybe if you didn't stop at the comma you could read , or during the Application_Start event in the Global.asax file.
. So those looks practically equal anyway
😆 😆
Surely, either code or docs must be updated
from embeddedresourcevirtualpathprovider.
ta v. much!
from embeddedresourcevirtualpathprovider.
Hi, I think we should reopen this topic.
I think it could be an issue to use AppInitialize
method. http://stackoverflow.com/a/330720/471213 shows that only one class can expose a public static void AppInitialize()
method or then you get a compiler error.
Please forgive for insisting on this topic, but I want to discuss the design choice of using the App_Code strategy for two reason
- (Subjective) I personally believe, IMHO, that it is bad design to use "magic methods" as similar as the magic number antipattern (shame on Microsoft first!!). For example I avoid like death using magic events Application_Start and Application_End in Global.asax, instead I use the Init method to wire proper event listeners
- (Objective) If a developer uses his own AppInitialize, it would conflict with ERVPP's, thus I believe all open source projects should consider the worst case scenario
Obviously I could, and maybe did already, change the code from App_Code to App_Start in my project, but I care about discussing and sharing thoughts to make better software.
Thank you for your time.
from embeddedresourcevirtualpathprovider.
I'm inclined to agree with you, but I'm trying to remember why I used app_code in the first place.
I suspect that in order to have the package work immediately after INSTALL-PACKAGE it was easier to use App_Code than attempt to modify someone's global.asax using some kind of nuget installer.
I'm not sure if a WebActivator/preapplicationstartmethod can be used or not to achieve the same thing or not, but if so perhaps that would be a better way.
I happy with the project as it stands (as you mentioned, it is easy to work around), but would accept a PR to the effect that:
- for new users who run install-pacakge: the VPP will work without requiring further developer input
- for existing users who run update-package: either they will be unaffected, or they will get an immediate run-time exception with a helpful message if the provider is registered twice (once by app_code, once by the method in the PR)
- the global.asax isn't modified. Some projects don't use it as they use startup.cs
from embeddedresourcevirtualpathprovider.
I know this topic is (getting) old, but I have to agree with djechelon. I placed the following in a class in App_Start:
using System.Linq;
using System.Reflection;
[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(Shell.EmbeddedResourceProviderStart), "Start")]
namespace Shell
{
public static class EmbeddedResourceProviderStart
{
public static void Start()
{
var assemblies = System.Web.Compilation.BuildManager.GetReferencedAssemblies()
.Cast<Assembly>()
.Where(a => a.GetName().Name.StartsWith("System") == false);
var vpp = new EmbeddedResourceVirtualPathProvider.Vpp(assemblies.ToArray())
{
//you can do a specific assembly registration too. If you provide the assemly source path, it can read
//from the source file so you can change the content while the app is running without needing to rebuild
//{typeof(SomeAssembly.SomeClass).Assembly, @"..\SomeAssembly"}
};
System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(vpp);
}
}
}
This also works when placed in the assembly providing the resources, thus making it more of a self-contained solution as well (might want to restrict it to declaring assembly only though in that case). Only thing needed in the startup project to make this work is to setup the web.config handlers section, no direct references required to ERVPP either.
Would you be willing to accept this as a PR? Also with further restriction to declaring assembly?
from embeddedresourcevirtualpathprovider.
Related Issues (20)
- Trying to get working with MVC 4 HOT 6
- Does not work in IIS HOT 1
- Is this work for Asp.net 5? (Asp.net vNext, Asp.net MVC 6) HOT 3
- Files 'placeholder.txt' and content/RegisterVirtualPathProvider.cs in a config package
- Usage with MVC bundles HOT 2
- Simple support for a little diagnostics HOT 2
- Pull requests get deployed to NuGet HOT 1
- Repository contains binaries in sample projects HOT 4
- Does not support complicated folder structures HOT 1
- Using "Enabling debugging for embedded razor views" doesn't works HOT 6
- VPP Not Working on Integrated IIS7 Azure HOT 4
- Locked assembly file after Publish HOT 12
- Split the package onto two ones: core and bootstrapper HOT 3
- Bundling and filenames with dots HOT 1
- Load views from different assemblies based the URL
- Please remove content scripts HOT 10
- Publish Precompiled project not working HOT 2
- EmbeddedResourcePath Regex Parser Bug HOT 2
- How do I get the VPP to pick-up changes without restarting my web app? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from embeddedresourcevirtualpathprovider.