Microsoft.Practices.ServiceLocation.ActivationException using Xamarin Autofac - xamarin

I am building an aaplication in Xamarin for IOs and sometimes I get these errors.
Microsoft.Practices.ServiceLocation.ActivationException: Activation
error occurred while trying to get instance of type
SurveyNavigationPage, key ""
I can't figure out why am I getting them and can't even trace them to where they are coming from...
I guess I have done something wrong in the Dependancy Injection. I am using Autofac and Service Locator. Below I will demonstrate how I implement the dependancy injection in my project and possibly someone can spot my error.
My code is in the PCL part of the Xamarin project but the error happens iOS Application class for some reason in the UIApplication.Main(args, null, "AppDelegate"); Well at least that is where it crashes if I debug..
My PCL App class instatiates the dependancy injection class like this:
public App()
{
SetUpDIContainer();
InitializeComponent();
MainPage = new NavigationPage(ServiceLocator.Current.GetInstance<MainPage>());
}
private void SetUpDIContainer()
{
var container = new DependencyInjection();
container.Initialize();
}
The Dependancy Injection class looks like this:
public class DependencyInjection
{
private IContainer _container;
public void Initialize()
{
BuildContainer();
SetServiceLocator();
}
private void BuildContainer()
{
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(RestRepository<>)).As(typeof(IRest<>));
builder.RegisterType(typeof(PageService)).As(typeof(IPageService));
builder.RegisterType<SurveyController>();
builder.RegisterType<LocationController>();
builder.RegisterType<ClientController>();
builder.RegisterType<RepositoryService>();
builder.RegisterType<MainViewModel>();
builder.RegisterType<SurveyNavigationViewModel>();
builder.RegisterType<EditSurveyViewModel>();
builder.RegisterType<ClientPageViewModel>();
builder.RegisterType<BaseViewModel>();
builder.RegisterType<MainPage>();
builder.RegisterType<SurveyNavigationPage>();
builder.RegisterType<SurveyPage>();
builder.RegisterType<EditSurvey>();
builder.RegisterType<ClientPageView>();
builder.RegisterType<App>();
var http = new HttpClient();
builder.RegisterInstance(http).As<HttpClient>();
_container = builder.Build();
}
private void SetServiceLocator()
{
var csl = new AutofacServiceLocator(_container);
ServiceLocator.SetLocatorProvider(() => csl);
}
}
It is a very strange error as it comes up sometimes and sometimes it doesn't and I can't spot what exactly has to happen in order for it to happen.

Related

RegionManager not injecting properly

I'm trying to pass our application that was using the old Prism 4.0 to latest Prism 7.1.0.431
I'm almost done, everything compiles. Dependency injection has been updated to use latest Unity. So everything seems back on track as I see injection working somewhat.
Though I still have a problem with Module loading: region manager cannot be resolved. I think I'm missing something in my initialization code but cannot find any relevant documentation on that. Try to get into all Prism.Wpf samples but could find relevant code.
Injecting the region manager within module is probably not a good practice from the code I'm seeing while search an answer to my issue, but bear with me that right now it's a huge application and would want to avoid changing that as much as possible:
Here is the exception error I'm having:
EXCEPTION: Prism.Modularity.ModuleInitializeException: An exception occurred while initializing module 'AdvancedExportModule'.
- The exception message was: Resolution of the dependency failed, type = 'Codex.Modules.AdvancedExport.AdvancedExportModule', name = '(none)'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, Prism.Regions.IRegionManager, is an interface and cannot be constructed. Are you missing a type mapping?
Am I missing something initialization code for the RegionManager to be mapped and injected correctly by Unity?
Here are the code sample, I tried to simply the most of it and hopefully it's enough for you to understand what's wrong...
This my App.xaml:
<prism:PrismApplication x:Class="Codex.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
<ResourceDictionary Source="Resources/Merged.xaml"/>
</Application.Resources>
</prism:PrismApplication>
And in my Code behind App.xaml.cs
namespace MyNamespace
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Threading;
using Prism.Ioc;
using Prism.Logging;
using Prism.Modularity;
using Prism.Unity;
public partial class App : PrismApplication
{
private static ILoggerFacade Logger { get; set; }
public static void Main()
{
var application = new App();
application.InitializeComponent();
application.Run();
}
protected override void OnStartup(StartupEventArgs startupEventArgs)
{
base.OnStartup(startupEventArgs);
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
var modulesFilePaths = new Dictionary<string, string>();
modulesFilePaths.Add("Namespace.Modules.Module1.dll", "Namespace.Modules.AdvancedExport.Module1Module");
var pathToExecutingLibrary = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName;
foreach (KeyValuePair<string, string> moduleFilePath in modulesFilePaths)
{
var referenceUri = Path.Combine(pathToExecutingLibrary, moduleFilePath.Key);
var assembly = Assembly.LoadFrom(referenceUri);
var type = assembly.GetType(moduleFilePath.Value);
moduleCatalog.AddModule(
new ModuleInfo(type)
{
ModuleName = type.Name,
Ref = referenceUri,
InitializationMode = InitializationMode.WhenAvailable
});
}
moduleCatalog.Initialize();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
ConfigureViewModelLocator();
var containerExtension = CreateContainerExtension();
containerRegistry.RegisterInstance(containerExtension);
// These methods have been commented out they are use to register all the types of the application.
//RegisterSettings(containerRegistry);
//RegisterServices(containerRegistry);
//RegisterHandlers(containerRegistry);
//RegisterWrappers(containerRegistry);
containerRegistry.RegisterInstance(Dispatcher.CurrentDispatcher);
}
protected override Window CreateShell()
{
Window mainShell = Container.Resolve<MainShell>();
return mainShell;
}
}
}
You're doing too much and the wrong things in your overrides. Example: RegisterTypes should just register types...
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// this has already been called by the base class: ConfigureViewModelLocator();
// this has also been called by the base class: var containerExtension = CreateContainerExtension();
// containerRegistry.RegisterInstance(containerExtension);
// These methods have been commented out they are use to register all the types of the application.
//RegisterSettings(containerRegistry);
//RegisterServices(containerRegistry);
//RegisterHandlers(containerRegistry);
//RegisterWrappers(containerRegistry);
containerRegistry.RegisterInstance(Dispatcher.CurrentDispatcher);
}
You should review the source code to get an understanding of how the overrides are supposed to be called. Essentially, they should not call each other, just do their own work.

Issue with Simple Injector while using with Web API

I am having issue using Simple Injector with WebAPI project that gets created default with VS 2015.
I am having the AccountController having the below constructor
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager,
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
}
In order to register these I used the below code in Simple Injector
// Create the container.
var apiContainer = new Container();
apiContainer.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
apiContainer.Options.ConstructorResolutionBehavior = new ConstructorBehavior();
//register the classes that we are going to use for dependency injection
apiContainer.Register<IUserStore<ApplicationUser>>(() => new UserStore<ApplicationUser>(new ApplicationDbContext()),Lifestyle.Scoped);
apiContainer.Register<IDataProtector>(() => new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider().Create("ASP.NET Identity"),Lifestyle.Transient);
apiContainer.Register<ISecureDataFormat<AuthenticationTicket>, SecureDataFormat<AuthenticationTicket>>(Lifestyle.Transient);
apiContainer.Register<ITextEncoder, Base64UrlTextEncoder>(Lifestyle.Scoped);
apiContainer.Register<IDataSerializer<AuthenticationTicket>, TicketSerializer>(Lifestyle.Scoped);
//apiContainer.RegisterCommonClasses();
//register the webapi controller
apiContainer.RegisterWebApiControllers(configuration);
but after this I am getting the warning message that says
[Disposable Transient Component] ApplicationUserManager is registered as transient, but implements IDisposable.
Can someone Please help me with this how to resolve this ? With Default Web api project with VS 2015 it adds Account controller and that use ApplicationUserManager and has below details
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
Another issue I am getting as below
The constructor of type HttpConfiguration contains the parameter with name 'routes' and type HttpRouteCollection that is not registered. Please ensure HttpRouteCollection is registered, or change the constructor of HttpConfiguration.
This is with the HelpController as it uses the below details:
public HelpController()
: this(GlobalConfiguration.Configuration)
{
}
public HelpController(HttpConfiguration config)
{
Configuration = config;
}

MVVMCross 5.3.2 UWP: Where to Get IMvxWindowsFrame for MvxFormsUwpViewPresenter

I'm working out of the Xamarin Forms for MVVMCross 5 Solution Template and updated the packages to the latest version (5.3.2 for MVVMCross). Doing that changes some namespaces around particularly in the UWP project.
It seems that I need to resolve IMvxViewPresenter as MvxFormsUwpViewPresenter which takes a IMvxWindowsFrame as an argument. In the setup file method of Setup.cs there's a XamlControls.Frame rootFrame passed as an argument but I'm not sure if that's suppose to be cast somehow as IMvxWindowsFrame.
Where can you pull the object that implements IMvxWindowsFrame from or is there another way to turn the rootFrame into an IMvxWindowsFrame legitimately.
public class Setup : MvxFormsWindowsSetup
{
private readonly LaunchActivatedEventArgs _launchActivatedEventArgs;
public Setup(XamlControls.Frame rootFrame, LaunchActivatedEventArgs e) : base(rootFrame, e)
{
_launchActivatedEventArgs = e;
// Mvx.RegisterSingleton<IMvxWindowsFrame>(rootFrame);
}
protected override void InitializeFirstChance()
{
base.InitializeFirstChance();
Mvx.RegisterSingleton<Core.Services.ILocalizeService>(new Services.LocalizeService());
Mvx.RegisterSingleton<ISettings>(CrossSettings.Current);
Mvx.RegisterType<IMvxViewPresenter, MvxFormsUwpViewPresenter>();
}
protected override MvxFormsApplication CreateFormsApplication()
{
return new Core.FormsApp();
}
protected override IMvxApplication CreateApp()
{
return new Core.MvxApp();
}
protected override IMvxTrace CreateDebugTrace()
{
return new Core.DebugTrace();
}
}
public sealed partial class MainPage : WindowsPage
{
public MainPage()
{
this.InitializeComponent();
var start = Mvx.Resolve<IMvxAppStart>();
start.Start();
var presenter = Mvx.Resolve<IMvxViewPresenter>() as MvxFormsUwpViewPresenter;
LoadApplication(presenter.FormsApplication);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
}
EDIT: I've been looking more into the class MvxFormsWindowsSetup in the source code at https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross-Forms/MvvmCross.Forms.Uwp/Platform/MvxFormsWindowsSetup.cs. It appears that in the method CreateViewPresenter that the IMvxViewPresenter is registered as a singleton with the MvxWrappedFrame already inside but by default the code does not resolve when calling var presenter = Mvx.Resolve() as MvxFormsUwpViewPresenter; in the windows page. Possible bug? Trying to see if I can resolve it myself.
Looks like it fails to resolve even if I put the code right after when Mvx is suppose to register the type / singleton
protected override IMvxWindowsViewPresenter CreateViewPresenter(IMvxWindowsFrame rootFrame)
{
var presenter = new MvxFormsUwpViewPresenter(rootFrame, FormsApplication);
Mvx.RegisterSingleton<IMvxFormsViewPresenter>(presenter);
var presenter2 = Mvx.GetSingleton<IMvxViewPresenter>() as MvxFormsUwpViewPresenter;
return presenter;
}
When updating to MvvmCross 5.3.2 for UWP, the presenter needs to resolve as IMvxFormsViewPresenter rather than IMvxViewPresenter. Change the interface type and it should load properly.
public MainPage()
{
this.InitializeComponent();
var start = Mvx.Resolve<IMvxAppStart>();
start.Start();
var presenter = Mvx.Resolve<IMvxFormsViewPresenter>() as MvxFormsUwpViewPresenter;
LoadApplication(presenter.FormsApplication);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}

MVC5 dependency injection issue

I have created an application using MVC5 with the onion architecture approach. The solution contains 3 projects (core, infrastructure, and UI). The UI contains both Web API controllers and MVC controllers. The issue I’m running into is dependency injection. I have installed Unity.MVC5 & Unity.WebApi. My UnityConfig.cs under App_Start Looks like this:
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IPricingService, PricingService>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
My global.asax looks like this:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
UnityConfig.RegisterComponents();
}
To test out my controller, I defined my home controller like this:
private readonly IPricingService _pricingService;
public HomeController(IPricingService PricingService)
{
this._pricingService = PricingService;
}
When running home page I get
No parameterless constructor defined for this object.
Now, moving to another test scenario, I created a web api controller and looks like this:
private readonly IPricingService _pricingService;
public TestApiController(IPricingService PricingService)
{
this._pricingService = PricingService;
}
Testing the web api generates this error:
An error occurred when trying to create a controller of type 'TextApiController'. Make sure that the controller has a parameterless public constructor.","exceptionType":"System.InvalidOperationException"
Not sure what I'm missing. Please advise.
You are supposed to inject the Unity.WebApi.DependencyResolver into the WebApi configuration not in GlobalConfiguration.Configuration.DependencyResolver.
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
// Other Web API configuration not shown.
}
You also need to implement a child container in the BeginScope method as shown in this MSDN article.

How do I use Universal Membership Provider, EF, and MiniProfiler together?

If I use the Universal Membership Provider and a seperate database, Entity Framework and enable Mini Profiler for EF 4.2. I get error {"There is already an object named 'Applications' in the database."} when I first hit a line checking user credentials in my home view.
If I turn remove MiniProfilerEF.Initialize(); then I stop getting the error.
Any ideas?
Can I stop profiling the defaultconnection?
I have been banging my head against this issue for awhile now. Did some more digging today and was able to get it working. Here is what I did. In MiniProfiler.cs I defined two methods as follows:
public static DbConnection GetConnection()
{
var connectionString = ConfigurationManager.ConnectionStrings["MyModelConnectionString"].ConnectionString;
var entityConnStr = new EntityConnectionStringBuilder(connectionString);
var realConnection = new SqlConnection(entityConnStr.ProviderConnectionString);
return realConnection;
}
public static IMyModelsInterface GetProfiledContext()
{
var connection = new MvcMiniProfiler.Data.EFProfiledDbConnection(GetConnection(), MiniProfiler.Current);
var context = connection.CreateObjectContext<MyModel>();
return context;
}
NOTE: These two methods probably shouldn't be defined in MinProfilerPackage, but this was my first past/hack to get it working.
Then call GetProfiledContext() and use the context returned whenever you want the queries profiled. I injected this profile context into my controller factory using Ninject. My call looks something like this:
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
private void AddBindings()
{
var context = MiniProfilerPackage.GetProfiledContext();
IUnitOfWork uow = new UnitOfWork(context);
ninjectKernel.Bind<IRepository>().To<GenericRepository>().WithConstructorArgument("paramUnitOfWork", uow);
// ... rest of the method
}
NinjectControllerFactory is my controller factory that gets set in Application_Start.
protected void Application_Start()
{
// Add in DI for controller and repo associations
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
// ... rest of the method
}

Resources