I have a Windows Phone app with Ninject IOC.
At some point I realized that my MainPage.xaml.cs (initial page of the application that gets initialized first) need to have a constructor with parameters.
I have added params to a constructor like this:
public partial class MainPage : PhoneApplicationPage
{
private readonly Settings _settings;
// Constructor
public MainPage(Settings _settings)
In my Ninject modules I have the binder for Settings type:
this.Bind<Settings>().ToSelf().InSingletonScope();
However, whenever I am to run an app, I get a MissingMethodException at startup.
I have worked around this problem by retaining a parameterless constructor in my MainPage(), and I use a service locator pattern with Ninject to get the Settings instance.
I want to know if there is a way for me to still have my app service locator free?
I'm afraid this isn't possible with the way the Silverlight navigation works. You have to have the parameterless constructor. Typically you would use the service locator to resolve your ViewModel which is where you need your dependencies injected, rather than your view.
As a side note don't fall into the trap of thinking that you should be developing your mobile apps the same way as you do desktop apps. The same rules don't automatically apply. IOC is an Enterprise Design Pattern, that aims to reduce the complexity of large apps with many developers developed over long periods. Phone apps are typically small apps with few developers developed over short periods - so its not necessarily true to that you have to rigidly follow the design pattern to the letter or even at all.
Related
I had a webapi in which I was using app.CreatePerOwinContext in startup.cs file but I want to migrate that webapi to .net core 2.1. So I have stuck at this point as I can't fine any alternate for CreatePerOwinContext.
Here is my webapi code:
public static UserManager<IdentityUser> Create(IdentityFactoryOptions<UserManager<IdentityUser>> options, IOwinContext context)
{
var manager = new UserManager<IdentityUser>(new UserStore());
return manager;
}
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext<UserManager<IdentityUser>>(Create);
...
}
So how can I convert the above code in .net core 2.1?
That method was used as a service locator to load up dependencies and then access them throughout your code. Service location on its own is considered an anti-pattern, and is not recommended for use in the vast majority of real world situations.
Instead, people use IOC containers now to manage their dependency injection. In ASP.NET MVC Core, there's now a lightweight and "good enough" IOC container provided for you as part of the framework.
Microsoft provides an overview in this article, but the short version is that in your Startup.cs you register your dependency tree under ConfigureServices (usually using an extension method so Startup.cs doesn't get too large).
After you've registered your dependencies, you load them either through property injection, constructor injection, or method parameter injection. This results in cleaner code that is more maintainable than standard service location.
Edit:
If you truly insist on managing a service locator either because the technical debt is acceptable or because the business case warrants the current design, then I suggest you transition your work from OwinContext over to HttpContext.
In ASP.NET Core, you access the HttpContext by injecting the HttpContextAccessor into your class, and changing your OwinContext calls to pull from the key value store in HttpContext.
Instructions for injecting HttpContextAccessor can be found in this SO answer. Simply store KVPs using HttpContext.Current.Application["myObject"].
I don't recommend doing this, but I'm willing to share it because I understand the reality of deadlines vs the idealism of architecture.
I register my Xamarin form page with Autofac container on my App that inherits PrismApplication för Autofac
_container.RegisterTypeForNavigation<MasterLayoutPage_View, MasterLayoutPageViewModel>("MasterLayoutPage");
Then I navigate like this:
await NavigationService.NavigateAsync("MasterLayoutPage");
But it always says that MasterLayoutPage is not registered.
But when I check my Container for registered types it's there, fully added as the registration above.
Have I missed something? It worked with Unity I just change to Autofac.
I found this kind of odd and wonder if it might be a bug or if NavigationService with Autofact can't register the type as Unity can?
Seems like my problem was that I did not register the pages inside the override method RegisterTypes on App.xaml.cs I registered the types on the Initialize overridden method. It did work with Unity, not sure why it does not work the same way with autofac when it's the same container I use... Maybe prismApplication for unity has some difference then PrismApplication for Autofac, I shall take a look at the implementations of those two
I'm trying to get myself familiar with MVC3 and autofac but I've encountered small problem that I'm having trouble resolving.
I am using autofac integrated with MVC3 and all works well, pages are loading correctly, dependencies are being injected and that's cool. What's bugging me is how to use autofac's Container or MVC's DependencyResover in class library project.
I'm trying to create static class that will help me handle domain events. I simply want to be able to call the method with event parameter and everything should be handeled by this class. Here is code:
public static IContainer Container { get; set; }
public static void Raise<T>(T e) where T : IDomainEvent
{
foreach (var eventHandler in DomainEventManager.Container.Resolve<IEnumerable<EventHandlers.Handles<T>>>())
{
eventHandler.Handle(e);
}
}
As you can see it's pretty straightforward and everything would work great if it wasn't MVC approach. Some of my dependencies are registeres as InstancePerHttpRequest (NHibernate' session), while other are registered as InstancePerDependency or SingleInstance. Thus when I try to use container created in my UI project, I get exception that there is no httpRequest tag available.
How can i reuse the Container created in web project to get access to all of it's features, including InstancePerHttpRequest and httpRequest tag?
Or maybe there is other solution to my problem? I was thinking about using delegate function to obtain event handlers, but I cannot (can I?) create generic delegate that I would not need to initialize with concrete type at time of assignment.
Why I want to do this using static class is basically every entity and aggregate or service needs to be able to raise domain event. Injecting EventManager into every one of these would be troublesome and static class is exactly what would resolve all my problems.
If anyone could help me get my head around it I would be grateful.
Cheers, Pako
You shouldn't be referencing your container directly from your app code. This looks like the Service Locator anti-pattern. The correct action is to pass your objects the services they need to do their jobs, usually done through constructor parameters. BUT... if you are going to insist on depending on a global static, then at least model EventManager as a singleton, such that usage would look like:
EventManager.Current.Raise<SomeEvent>(someObject);
and then you can set EventManager.Current equal to a properly constructed instance when your app is initialized.
What is the recommended way to set up / inject dependencies in a viewModel after tombstoning given that when the app deactivates you typically add the ViewModel to the State dictionary and then before your app reactivates the framework deserialises the ViewModel which requires a default constructor?
If I have the class below, I would like to have dependency injection create an instance of "MyVM" injecting the dependencies for IServiceA and IServiceB. Having a default constructor would not set up the requried dependecies.
public class MyVM(IServiceA svca,IServiceB svcB)
{
}
How should the ViewModel be setup in a tombstoning scenario here?
I don't know if you're using a specific MVVM framework but Caliburn Micro has some built in features for tombstoning.
A little snippet from the docs:
public class PivotPageModelStorage : StorageHandler<PivotPageViewModel> {
public override void Configure() {
this.ActiveItemIndex()
.InPhoneState()
.RestoreAfterViewLoad();
}
}
That example is storing the ActiveItemIndex, a property on PiveotPageViewModel, in phone state but it can also store entire object graphs in PhoneState, AppSettings, or your own custom implementation. You get all that by inheriting from StorageHandler. With CM you don't have to worry about re-injecting services, it will handle that for you as it has it's own built in container.
CM WP7 Docs
In a recent Hanselman post about building a WP7 app he talked a bit about TombstoneHelper. I haven't used this one but it looks interesting.
I have created a custom Class Library(named it as MiEngine), in that I have created an Application class(MiEngineApp.xaml and MiEngineApp.xaml.cs). In my project(application), I have integrated the Class Library and my project's App class extends the Class Library's Application class(ie. public partial class App:MiEngineApp). I have made changes in the App.xaml also using the z name space.
I want to implement the Application life cycle methods only in the Class Library's Application class not in the project's Appication class. But If I do not implement the Application Life cycle methods in the project's Application class, at run time XamlParseException is thrown in the MiEngineApp.g.i.cs file's InitializeComponent method. I have no clue why this happens and how to implement the life cycle methods only in the Class library's Application class. Please give me some idea!
You could put the logic for the lifecycle events in the library and then call them from the event handlers in the (each?) app. Yes this means adding 4 lines of code to the app but this is the best solution currently available.
As per the default comments in app.xaml, handlers for the Launching, Activated, Deactivated and Closing events of the PhoneApplicationService are REQUIRED.