tldr: Is there any way I can choose which constructor to use when I register a type?
I have followed the instructions to create a platform specific inversion of control as outlined in Inversion of control.
In your core project, you can declare an interface and you can use that interface in your classes there ...
In each UI project, you can then declare the platform-specific implementation ...
You can then register these implementations in each of the platform-specific Setup files - e.g. you could override MvxSetup.InitializeFirstChance
So in my core project I have defined the following interface
public interface IJob
{
void AddAction(Action action);
}
In my Android project I have implemented the interface as follows
public class CustomJob: Job, IJob
{
private Action _action;
public CustomJob(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public CustomJob() : base(new Params
(Jobs.Priority.MID
).RequireNetwork().Persist())
{
//_action = action;
}
public override void OnAdded()
{
}
protected override void OnCancel(int p0, Throwable p1)
{
}
public override void OnRun()
{
_action.Invoke();
}
protected override RetryConstraint ShouldReRunOnThrowable(Throwable p0, int p1, int p2)
{
return RetryConstraint.Cancel;
}
public void AddAction(Action action)
{
_action = action;
}
}
And I overrode the implementation of InitializeFirstChance
in Setup.cs
protected override void InitializeFirstChance()
{
Mvx.IoCProvider.RegisterType<IJob, CustomJob>();
base.InitializeFirstChance();
}
However, I get the following stacktrace at runtime
{MvvmCross.Exceptions.MvxIoCResolveException: Failed to resolve parameter for parameter javaReference of type IntPtr when creating CustomJob. You may pass it as an argument at MvvmCross.IoC.MvxIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor, System.Collections.Generic.IDictionary
2[TKey,TValue] arguments) [0x0005a] in C:\projects\mvvmcross\MvvmCross\IoC\MvxIoCContainer.cs:648 at MvvmCross.IoC.MvxIoCContainer.IoCConstruct (System.Type type, System.Collections.Generic.IDictionary
2[TKey,TValue] arguments) [0x00031] in C:\projects\mvvmcross\MvvmCross\IoC\MvxIoCContainer.cs:413
Is there any way I can choose which constructor to use when I register a type? Thank you.
AFAIK you can't choose which constructor the Mvx's IoC engine will choose.
So one way is to make another class that implements your IJob
that has a reference to Job
internally and in the implementation of the class you pass the action to the Job
implementation.
public class JobHandler : IJob
{
private Job _customJob;
public JobHandler()
{
this._customJob = new CustomJob();
}
public void AddAction(Action action)
{
this._customJob.AddAction(action);
}
}
If you want you can do an IJobHandler
that inherits IJob
so that you can use that interface for the JobHandler
implementations and the IJob
for you actual Job
Another way is to add stub parameters to the parameterless constructor so that it takes more parameters than the other and gets elected by the IoC engine (I'm not entirely sure that it would work, but I think so). But it is a bit messy.
Another way is you to tell the IoC engine how you want to construct your IJob
:
Mvx.IoCProvider.RegisterType<IJob>(() => new CustomJob());
HIH