I want to observe livedata with
viewlifecycleowner
instead of
this
but it is not resolved. What is the dependency for it?
https://developer.android.com/jetpack/androidx/releases/lifecycle
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
Related
is possible to resolve/ create a new instace of object thats are not registered in Swinject container? In Unity dependency injection for c# (from Microsoft) is it.
I Want to resolve viewModel class, that have dependence for some protocols.
For example:
I have registred IFileManager in container:
container.register(IFileManager.self) { _ in FileManager() }.inObjectScope(ObjectScope.container)
and me viewModel have dependece for IFileManager
class AwesomeViewModel{
init (fileManager: IFileManager) {
....
}}
now i want to create new instance of AwesomeViewModel using Swinject resolver, and I want all the dependencies to be added to the init, but it doesn't work
viewModel = AppDelegate.container.resolve(AwesomeViewModel.self)
and ViewModel is nil
No, Swinject is not able to infer which initialisation method you expect to be used for instantiation of AwesomeViewModel. You need to explicitly define it first:
container.register(AwesomeViewModel.self) {
AwesomeViewModel(fileManager: $0.resolve(IFileManager.self)!)
}
Admittedly, this might get quite cumbersome if you have classes with many dependencies. If that becomes a problem, I suggest you check out the SwinjectAutoregistration extension. It enables you to write:
container.autoregister(AwesomeViewModel.self, initializer: AwesomeViewModel.init)
In my current application, I am using a 'selfmade' Observable class in order to implement the observer pattern. Observers (implementing an interface) can listen to certain events.
I am switching more and more of the project over to using an IoC container, but I fail to find a good place in the code to register the observers with the observable.
The ways to do this that I see are:
A) Inject the observable into the observer.
The constructor shouldn't do actual work, but even with method- or field injection this couples the observer with the observable. This is also the case if it's the other way around.
B) Create an observable factory and do it there.
In this case creating the observable depends on the implementations of several observers.
C) Create the observers by factory and do it there.
While this seems best to me concerning coupling, it turns out bad concerning DRY. In some cases the factory ends up being a copy of the fields and constructor of the observer, plus the observable and plus the one line of code for the registering.
Is there a way to handle this registering in a clean way? If not, are there compelling arguments to use a certain way over the others?
The solution was discovering the difference between Resolve() and Instantiate() methods.
I was always using Resolve(). With that, I would receive an Observer in the way it has been bound to the container.
However, Instantiate() does not care about how the class is bound to the container. It creates the class the standard way, but still injects the dependencies. So this can be used inside the factory for the observer.
The dependent ViewModel gets injected via the constructor (IoC container).
Example: ProductSelectionViewModel uses ShoppingBasketViewModel.
Is this a common practice or is this THE recommended way? I don´t think so...
How should it be done right?
Should the view use the 2 ViewModels?
Mediator pattern?
Event driven?
Personally I don´t like the last one.
There's nothing wrong with a view model having a direct reference to another view model, if it is a required dependency, then injecting it via the constructor is fine.
If you wish for a view model to be able to create new instances of another view model, then injecting a view model factory type would be the way to go.
I remember I have read somewhere here in SO (maybe I was dreaming) that I can enable a "hidden" debug feature of Autofac, so that it can give me more information on what Autofac is doing in the background.
I asked because I just encountered a bug in my project. After I have added the following code into my AutofacModule:
builder.RegisterAssemblyTypes(typeof(MainWindowViewModel).Assembly)
.AssignableTo(typeof(ViewModelBase))
.EnableClassInterceptors()
.InterceptedBy(typeof(NotifyPropertyChangedInterceptor));
when compile, at:
using (var container = builder.Build())
{
...
}
Autofac throws:
System.NotSupportedException was unhandled. Parent does not have a default constructor. The default constructor must be explicitly defined.
But it didn't tell me which class does not have a default constructor (maybe I have missed something in the output window?). I ended up opened all my ViewModel classes one by one... to check if they have a default constructor.
So it would be wonderful for me if Autofac has a hidden debug feature. If not, is there an automatic way to find all classes which don't have a default constructor?
Thanks
(sorry for my English)
this isn't an Autofac exception - it looks like it might be a WPF one? If you can get the call stack from the debugger when the exception is thrown it should offer a clue.
Cheers!
I'm adding autofac to an existing project and some of the service implementations require their Initialize method to be called and passed configuration information. Currently I'm using the code:
builder.Register(context =>
{
var service =
new SqlTaxRateProvider(context.Resolve<IUserProvider>());
service.Initialize(config);
return service;
}
).As<ITaxService>()
.SingleInstance();
which works but I'm still creating the object myself which is what I'm trying to get away from this and allow autofac to handle it for me. Is it possible to configure a post create operation that would carry out the custom initialisation?
To give you an idea of what I'm after ideally this would be the code:
builder.RegisterType<SqlTaxRateProvider>()
.As<ITaxService>()
.OnCreated(service=> service.Initialize(config))
.SingleInstance();
Update:
I am using Autofac-2.1.10.754-NET35
.OnActivating(e => e.Instance.Initialize(...))
should do the trick.
You might also investigate the Startable module (see the Startable entry in the Autofac wiki).
Mark's suggestion to do initialisation in the constructor is also a good one. In that case use
.WithParameter(new NamedParameter("config", config))
to merge the config parameter in with the other constructor dependencies.