I can't seem to find an equivalent in Nancy for System.Web.HttpContext.Current.Server.MapPath() in the Nancy framework.
I just want to load a textfile relative to the application service.
I see this in the assembly
using Nancy;
using System;
namespace Nancy.Hosting.Self
{
public class FileSystemRootPathProvider : IRootPathProvider, IHideObjectMembers
{
public FileSystemRootPathProvider();
public string GetRootPath();
}
}
I'm not sure how to use.
update: I just figured out anything I need to load can just be read/written from the bin/relase/ directory. Is that the assumed way to do it in a Nancy Self Hosting environment? I guess that would make sense.
You can take a dependency on IRootPathProvider and use that to call GetRootPath() that will give you the root of your application and you can add from there (I would recommend using Path.Combine)
If you need this in a static class (such as an HtmlHelpers extension) where the IRootPathProvider dependency can't be injected, at least AFAIK, you can use AppDomain.CurrentDomain.BaseDirectory which is what DefaultRootPathProvider uses under the hood for .Net 4.x: https://github.com/NancyFx/Nancy/blob/master/src/Nancy/DefaultRootPathProvider.cs
Related
I once used SQLite for my android application. I made a Queries.cs file where I had all the queries stored (createDatabase, insertDatabase etc). I had a string as a class variable where I stored the path ot the folder I wanted to put in my .db file. It looked like this:
private string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
Now I want the same or at least the folder where the application sits in. But this time I need a way that'll be supported from iOS and form Android because it is necessary for this project. Do you know how I can do that?
Many thanks in advance
There is no unified way provided in Xamarin.Forms for this. You can leverage the DependencyService to reach it from your shared code and still differentiate per platform. This could look like this, define an interface in your shared code:
public interface IFilesystemService
{
string GetAppRootFolder();
}
Now create an implementation on Android like this:
public class FilesystemServiceAndroid : IFilesystemService
{
public string GetAppRootFolder()
{
return System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
}
}
For iOS the idea is the same, only the implementation may differ. You can, of course, extend this class as you like with the ability to read or write files for example.
Don't forget to adorn your namespace of the implementation with the [assembly: Xamarin.Forms.Dependency (typeof (FilesystemServiceAndroid ))] attribute. Like so:
[assembly: Xamarin.Forms.Dependency (typeof (FilesystemServiceAndroid ))]
namespace YourAppName
{
public class FilesystemServiceAndroid : IFilesystemService
{
// ... code here
}
}
You can now retrieve it in your shared code like this: var path = DependencyService.Get<IFilesystemService>().GetAppRootFolder();
You should use a Dependency Service in order to get platform specific file paths. A great tutorial on how to use SQLite in Xamarin.Forms can be found here which can be used in platform specific code as well.
So let me start off by saying "I know this isn't a best practice" and that I do not want to add the information from the app.config files to the web.config file... I've got a project that is a class library itself and it will be using a lot of class libraries as well.
Typically in my unit test project (used for testing) or my web project (that uses the lib in production) I have to add all of the configuration information. These libraries aren't going to be called differently from each project so I'm looking for a way to get the calling project to read the callee project's config file.
I've looked online and the only two things I've found so far are:
1) Don't do it. You need to add the information to the calling project's config file
example a) Read from App.config in a Class Library project
example b) Class Library project in ASP.NET reading from web.config and not app.config
example c) .Net app.config in library project
2) You shouldn't do it but I know how (no how to included :/)
example a) app.config for a class library
I've been doing it the "right" way for a while and that has left me with lots of web.config and test project config files with info duplicated from class lib app.config files. I really do think that there is a specific, justified use case for doing this.
Thanks!
The best practice that I know of is to avoid direct dependency on app.config/web.config from classes in your library, or maybe even classes in general. That doesn't mean that you don't use app.config. It means that your classes don't know they're using it.
For example,
public class MyClassThatDependsOnSomeSettings
{
private readonly ISettings _settings;
public MyClassThatDependsOnSomeSettings(ISettings settings)
{
_settings = settings;
}
public void DoSomething()
{
var settingA = _settings.SettingA;
}
}
public interface ISettings
{
int SettingA {get;}
string SettingB {get;}
}
Now you can consider MyClassThatDependsOnSomeSettings done. It doesn't require any access to a .config file. It just requires an instance of something that implements ISettings. That can read from .config.
public class SettingsFromConfiguration : ISettings
{
public int SettingA
{
get
{
string setting = ConfigurationManager.AppSettings["settingA"];
int value = 0;
int.TryParse(setting, out value);
return value;
}
}
public string SettingB
{
get { return ConfigurationManager.AppSettings["settingB"];}
}
}
Does it look like this just moves things around and does the same thing anyway? It does, almost. The big difference is that while you can use an implementation of ISettings that reads from app.config, you can also write other implementations. You can write one that uses hard-coded values, you could write a custom configuration section instead of using AppSettings, or if down the road you have an application with a JSON configuration file and no AppSettings your class can still work.
This applies the Dependency Inversion, which beneath everything means that classes should depend on abstractions (like interfaces) not concrete implementations.
Putting a requirement for ISettings in the constructor is called Dependency Injection, specifically constructor injection.
I'm trying to inject specific class into my WCF service but it doesn't work and I can't understand why. I'm VERY NEW to MEF and patterns, just trying to make it work. Watched series of videos to understand what it is about but bootstraping won't work in my case since it is not Silverlight
http://channel9.msdn.com/blogs/mtaulty/mef--silverlight-4-beta-part-1-introduction
Here is my Web application's Global.asax code. This is non MVC, just regular ASP.NET app:
private void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
var catalog = new WebScopedCatalog(new DirectoryCatalog(Server.MapPath("~\\bin")));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
FIRST, I'm not sure I even bootrstrap it properly.. SECOND, I'm using http://www.timjroberts.com/2011/02/web-scoped-mef-parts/ as a guidance for web-scoped parts. I need that because some injected objects supposed to live during request only.
Now, I have following class:
[Export(typeof(ITest))]
[WebPartCreationPolicy(WebCreationPolicy.Session)]
public class Test : ITest
{
public string TestMe()
{
return "Hello!";
}
}
And my service looks like:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MobileService
{
[Import]
public ITest MyTestClass { get; set; }
public MobileService()
{
int i = 10;
}
When breakpoint hits at i=10 - I have NULL inside MyTestClass. Clearly, MEF does not initialize this class for me. Am I missing something?
EDIT:
When I examine catalog - I see my class Exported but I don't see it imported anywhere...
EDIT 2:
Daniel, Thank you. It makes sense. It still feels litle like a magic for me at this point. Yes, WCF creates this service. Than I have MembershipProvider and various Utility classes that ALL need the same import. And I'm not creating neither of those classes so I can't have Mef creating them. (Service created by WCF, MembershipProvider created by who-knows-what, Utility classes have static methods..) I wanted to use Mef instead of storing my stuff in HttpContext.Current. My container object doesn't have SatisfyImports. It has SatisfyImportsOnce. What if I do it in many different constructors? Will Mef share same singleton or it will be creating new instance every time?
At this point I wonder if I should even use Mef in this particular scenario..
MEF won't satisfy imports for objects it doesn't create. What is it that creates MobileService? If it's not MEF, then the import won't be satisfied by default. Even if it is MEF, the import wouldn't be satisfied in the constructor- you can't set properties on an object you create until it is done being created (ie the constructor has finished).
You can call container.SatisfyImportsOnce(mobileService) to satisfy the imports of a part. You should try to avoid doing this everywhere you need a MEF import. If you can, you should export a part and import it from another part so that MEF handles the creation for you. However, it looks like this part may be created by WCF so you can't have MEF create it, and in that case it would be OK to use SatisfyImportsOnce.
Response to EDIT2: If you use the same container each time, MEF will by default only create one instance of the part with the export. You can set the CreationPolicy to NonShared (in either the export or import attribute) to change this.
As for whether it makes sense to use MEF the way you are trying to, I don't know enough about writing web services to give you any advice on that.
The web-scoped part creation policy that I wrote won't help with WCF services.
I've posted a new blog post that documents an approach to composeable WCF services:
http://www.timjroberts.com/2011/08/wcf-services-with-mef/
Basically, you need to implement a custom Instance Provider that is MEF-aware and can compose the WCF service object when it is created.
I wrote about how to compose your WCF in a generic way that its configuration based here:
Unit Testing, WCF and MEF
I actually built my solution on the code samples Tim Robert's provided in his post. only that I took it a bit further and instead of using code in the global asax i moved the configuration into the web.config so its easier to maintain.
public class MyHttpHandler : IHttpHandler
{
public MyHttpHandler() { ... }
public IUnityContainer Container { get; set; }
}
Is there a way to somehow get Container magically be set to a container I setup in global.asax?
Right now I can't find a way of doing it other than using AppDomain.CurrentDomain.GetData("container") as IUnityContainer.
Please let me know if there is a cleaner way of doing this.
First hit on google for asp.net mvc2 unity
http://weblogs.asp.net/shijuvarghese/archive/2010/05/07/dependency-injection-in-asp-net-mvc-nerddinner-app-using-unity-2-0.aspx
There are plenty of articles about MVC and Unity. You basically need to create a custom controller factory (in mvc2). MVC3 got a different solution.
Update
Use the BuildUp method in global.asax.
Sry. that was for existing objects. Why not just Register it and directly after Resolve it?
Singleton pattern may help you)
I would use service location instead.
Let's say I have a class called AppConfig:
public static class AppConfig
{
private static XDocument config =
public static AppConfig()
{
}
}
How do I XDocument.Load the ~App.Config file? Isn't it something like Server.SOMETHING? What namespaces do I need to include>
XDocument.Load(HttpContext.Current.Server.MapPath("~/web.config"));
is probably what you're looking for. This helper class "Server" lives on the "current" HttpContext inside the System.Web namespace, so add a
using System.Web;
to your code.
Marc
I think what is his problem, he is not able to get server class in his class
Server is property of the Page class that your page inherits from, it not a
global. if you are trying to access from a class, use
HttpContext.Current.Server.MapPath("");
and add reference
using System.Web;
OR can be get directly
System.Web.HttpContext.Current.Server.MapPath("");
I'm not sure why you're trying to do that ... if you want to access the values in your web.config or app.config (for client apps) there is already a wrapper class set up to do that named My.Settings.
Those app.config and web.config files are a pain in the keester to deal with directly.