问题
I have a ViewModel and I want to inject another Class into it. I am using Visual Studio with the latest version of Xamarin. I'm using Autofac for registering en resolving dependencies. But I'm new to it and I'm facing a problem which I can't find the solution to, even though it's probably simple.
This is the Class in which I want to inject another Class:
public IMessagingCenterWrapper MessagingCenterWrapper;
public LoginViewModel(IMessagingCenterWrapper messagingCenterWrapper){
MessagingCenterWrapper = messagingCenterWrapper;
}
Then in entry point of the app I have a function which initializes the container which registers and resolves dependencies
static IContainer container{ get; set; }
public App ()
{
InitializeComponent();
InitializeIOCContainer();
}
void InitializeIOCContainer()
{
var builder = new ContainerBuilder();
builder.RegisterType<LoginViewModel>();
builder.RegisterType<MessagingCenterWrapper>().As<IMessagingCenterWrapper>();
container = builder.Build();
var wrapper = container.Resolve<IMessagingCenterWrapper>();
var viewModel = container.Resolve<LoginViewModel>();
}
But I get an error when building at the line in the login View:
BindingContext = new LoginViewModel();
I'm getting the error because I don't initialize the parameter in the call.
But if I do that won't I destroy the whole principle of the IoC pattern. Eventually new class calls will be nested with other dependencies and I want to avoid that.
So my question is: how do I actually inject the the class parameter in the constructor?
回答1:
This is actually a service locator injection, since the injected element is a messaging center service. That's good news.
You don't have to pass in service constructors to view model constructors. Just request the service where you need it:
public LoginViewModel()
{
MessagingCenterWrapper = App.Container.Resolve<IMessagingCenterWrapper>();
}
Don't stick the view models into AutoFac unless they are indeed global. There are a lot of problems with this sort of fake IOC.
To make it easier overall, how about this:
// MUST BE PUBLIC
public static IContainer Container{ get; set; }
static App()
{
InitializeIOCContainer();
}
public App ()
{
InitializeComponent();
}
private static void InitializeIOCContainer()
{
var builder = new ContainerBuilder();
builder.RegisterType<MessagingCenterWrapper>().As<IMessagingCenterWrapper>();
Container = builder.Build();
// Don't stick view models in the container unless you need them globally, which is almost never true !!!
// Don't Resolve the service variable until you need it !!!! }
}
The complete code for these remarks is at https://github.com/marcusts/xamarin-forms-annoyances. See the solution called AwaitAsyncAntipattern.sln.
The GitHub site also provides links to a more detailed discussion on this topic.
来源:https://stackoverflow.com/questions/47287770/how-do-i-inject-a-constructor-dependency-into-a-viewmodel-using-xamarin-and-auto