Dagger 2, can not inject presenter in my activity - dependency-injection

I am new in Dagger2.
I have a problem with inject presenter in my activity
I try to resolve my problem after read this article https://android.jlelse.eu/inject-interfaces-without-providing-in-dagger-2-618cce9b1e29 but it was not helpe me. I hope someone help me, I spend all day tring to resolve it...
here is my modules:
#Module
class AppModule(private val appContext: Context) {
#Singleton
#Provides
internal fun provideContext(): Context {
return appContext
}
#Singleton
#Provides
internal fun providePreferences(): SharedPreferences {
return appContext.getSharedPreferences(
appContext.resources.getString(R.string.shared_preferences_name), Context.MODE_PRIVATE)
}
}
#Module
abstract class ActivityModule {
#Binds
abstract fun provideMakeCheckPresenter (p :
MakeCheckPresenter<MakeCheckMvpView>)
: MakeCheckMvpPresenter<MakeCheckMvpView>
}
here is my component:
#Component(modules = { AppModule.class, ActivityModule.class})
#Singleton
public interface AppComponent {
void inject(MakeCheckActivity makeCheckActivity);
}
here is my App class:
class App : android.support.multidex.MultiDexApplication() {
override fun onCreate() {
super.onCreate()
component = buildComponent()
}
protected fun buildComponent(): AppComponent {
return DaggerAppComponent.builder().appModule(AppModule(this)).build()
}
companion object {
var component: AppComponent? = null
private set
}
}
here is my activity:
class MakeCheckActivity : BaseActivity(), MakeCheckMvpView {
#Inject lateinit var presenter: MakeCheckMvpPresenter<MakeCheckMvpView>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.new_check_activity)
App.getComponent().inject(this)
}
}
here is my presenter:
class MakeCheckPresenter<V : MakeCheckMvpView>
#Inject constructor() : BasePresenter<MakeCheckMvpView>(), MakeCheckMvpPresenter<MakeCheckMvpView> {
override fun saveEnterpriseId(enterpriseId: Int) {
//model.enterpriseId
}
}
here is interfaces for presenter and view:
interface MakeCheckMvpView : MvpView {
}
interface MakeCheckMvpPresenter<in V : MakeCheckMvpView> : MvpPresenter<V> {
fun saveEnterpriseId(enterpriseId : Int)
}
and here base classes:
open class BasePresenter<V : MvpView> #Inject constructor(): MvpPresenter<V> {
}
abstract class BaseActivity : AppCompatActivity(), MvpView{
}
and always when i build i have this error:
...\di\component\AppComponent.java:62: error: ..ui.check_making.MakeCheckMvpPresenter<? super ...ui.check_making.MakeCheckMvpView> cannot be provided without an #Provides- or #Produces-annotated method.
e:
e: void inject(MakeCheckActivity makeCheckActivity);
how can I resolve it?

Related

How to initialize Swift class annotated #MainActor for XCTest, SwiftUI Previews, etc

We'd like to make use of the #MainActor Annotation for our ViewModels in an existing SwiftUI project, so we can get rid of DispatchQueue.main.async and .receive(on: RunLoop.main).
#MainActor
class MyViewModel: ObservableObject {
private var counter: Int
init(counter: Int) {
self.counter = counter
}
}
This works fine when initializing the annotated class from a SwiftUI View. However, when using a SwiftUI Previews or XCTest we also need to initialize the class from outside of the #MainActor context:
class MyViewModelTests: XCTestCase {
private var myViewModel: MyViewModel!
override func setUp() {
myViewModel = MyViewModel(counter: 0)
}
Which obviously doesn't compile:
Main actor-isolated property 'init(counter:Int)' can not be mutated from a non-isolated context
Now, obviously we could also annotate MyViewModelTests with #MainActor as suggested here.
But we don't want all our UnitTests to run on the main thread. So what is the recommended practice in this situation?
Annotating the init function with nonisolated as also suggested in the conversation above only works, if we don't want to set the value of variables inside the initializer.
Just mark setUp() as #MainActor
class MyViewModelTests: XCTestCase {
private var myViewModel: MyViewModel!
#MainActor override func setUp() {
myViewModel = MyViewModel(counter: 0)
}
}
Approach:
You can use override func setUp() async throws instead
Model:
#MainActor
class MyViewModel: ObservableObject {
var counter: Int
init(counter: Int) {
self.counter = counter
}
func set(counter: Int) {
self.counter = counter
}
}
Testcase:
import XCTest
#testable import Demo
final class MyViewModelTests: XCTestCase {
private var myViewModel: MyViewModel!
override func setUp() async throws {
myViewModel = await MyViewModel(counter: 10)
}
override func tearDown() async throws {
myViewModel = nil
}
func testExample() async throws {
await myViewModel.set(counter: 20)
}
}

Adding an interface to a Dart extention method

Is it possible to add an interface to a Dart extension? In Swift you can do this:
protocol MyProtocol {
associatedtype Item
mutating func nextItem() -> Item?
}
extension MyClass: MyProtocol {
public typealias Item = T
public mutating func nextItem() -> T? {
// ...
}
}
How do you do that in Dart? It seems this is not possible:
extension MyClassExtension<T> on MyClass implements MyInterface {
T? nextItem() {
// ...
}
}
It isn't possible to add an interface to a Dart extension. See the discussion here:
https://github.com/dart-lang/language/issues/475
https://github.com/dart-lang/language/issues/736
You have to manually add the methods from the interface as you would a normal extension method:
extension MyClassExtension<T> on MyClass<T> {
T? nextItem() {
// ...
}
}

Protocol 'App' can only be used as a generic constraint because it has Self or associated type requirements

a common example:
protocol Foo {
}
extension Foo {
static func abc() {
// ...
}
}
class Bar : Foo {
static func abc() {
// do something.
(self as Foo.Type).abc() // it works well
}
}
but if I add associatedtype (like SwiftUI.App) in protocol Foo, it report error:
protocol Foo {
associatedtype Body = Scene
}
extension Foo {
static func abc() {
// ...
}
}
class Bar : Foo {
static func abc() {
// do something.
(self as Foo.Type).abc() // it reports error
}
}
Protocol 'Foo' can only be used as a generic constraint because it has Self or associated type requirements
🤔 how to resolve it?

Xamarin.iOS with MVVMCross call only constructors at ViewControllers

Does anybody face this problem? I'm trying to implement MVVM using MVVMCross in Xamarin.iOS project, but in ViewController only constructor was called, neither ViewDidLoad nor ViewWillAppear. What's wrong? Or may be I miss something? Thank you.
public partial class VideosViewController : MvxViewController<VideoListViewModel>
{
public VideosViewController() : base(nameof(VideosViewController), null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
}
}
public class VideoListViewModel : MvxViewModel
{
private readonly IVideoService _videoService;
public CancellationTokenSource TokenSource => new CancellationTokenSource();
public VideoListViewModel(IVideoService videoService)
{
_videoService = videoService;
}
public override async Task Initialize()
{
await base.Initialize();
}
}

Call a method with dynamic class name in swift

How can we call class functions with a dynamic class name?
Assume the following example where I have two class with methods with same signature
class Foo{
class func doSomething()
}
class Foobar {
class func doSomething()
}
class ActualWork{
//call following method with a variable type so that it accepts dynamic class name
func callDynamicClassMethod(x: dynamicClass)
x.doSomething()
}
How can this be implemented so that x accepts values at run time
Edit: Sorry, I missed to mention that I was looking for any other ways other than protocol oriented approach. This is more of an exploratory question to explore if there is a more direct approach/pods/libraries to achieve this.
I liked this question, because it made me to think a lit'bit outside of the box.
I'll answer it, by dividing it into a few parts.
First
call class functions
Class function is basically a Type methods, which can be achieved using the static word inside the class context.
Taking that into account, you can get a simple solution, using protocol and passing the class reference (conforming to that protocol) like this:
protocol Aaa{
static func doSomething();
}
class Foo : Aaa{
static func doSomething() {
print("Foo doing something");
}
}
class FooBar : Aaa{
static func doSomething() {
print("FooBar doing something");
}
}
class ActualWork{
//Using class (static) method
func callDynamicClassMethod <T: Aaa> (x: T.Type) {
x.doSomething();
}
}
//This is how you can use it
func usage(){
let aw = ActualWork();
aw.callDynamicClassMethod(x: Foo.self);
aw.callDynamicClassMethod(x: Foo.self);
}
Second
In case you don't really need the method on the class context, you may consider using instance methods. In that case the solution would be even simpler, like this:
protocol Bbb{
func doSomething();
}
class Bar : Bbb{
func doSomething() {
print("Bar instance doing something");
}
}
class BarBar : Bbb{
func doSomething() {
print("BarBar instance doing something");
}
}
class ActualWork{
//Using instance (non-static) method
func callDynamicInstanceMethod <T: Bbb> (x: T){
x.doSomething();
}
}
//This is how you can use it
func usage(){
let aw = ActualWork();
aw.callDynamicInstanceMethod(x: Bar());
aw.callDynamicInstanceMethod(x: BarBar());
}
Third
If you need to use the class func syntax, as OP originally did:
class func doSomething()
You CANNOT simply use a protocol. Because protocol is not a class...
So compiler won't allow it.
But it's still possible, you can achieve that by using
Selector with NSObject.perform method
like this:
class ActualWork : NSObject{
func callDynamicClassMethod<T: NSObject>(x: T.Type, methodName: String){
x.perform(Selector(methodName));
}
}
class Ccc : NSObject{
#objc class func doSomething(){
print("Ccc class Doing something ");
}
}
class Ddd : NSObject{
#objc class func doSomething(){
print("Ccc class Doing something ");
}
#objc class func doOther(){
print("Ccc class Doing something ");
}
}
//This is how you can use it
func usage() {
let aw = ActualWork();
aw.callDynamicClassMethod(x: Ccc.self, methodName: "doSomething");
aw.callDynamicClassMethod(x: Ddd.self, methodName: "doSomething");
aw.callDynamicClassMethod(x: Ddd.self, methodName: "doOther");
}
Generics and Protocol oriented programming will do the job:
protocol Doable {
static func doSomething()
}
class Foo: Doable {
static func doSomething() {
debugPrint("Foo")
}
}
class Foobar: Doable {
static func doSomething() {
debugPrint("Foobar")
}
}
class ActualWork {
func callDynamicClassMethod<T: Doable>(x: T.Type) {
x.doSomething()
}
}
let work = ActualWork()
work.callDynamicClassMethod(x: Foo.self)
work.callDynamicClassMethod(x: Foobar.self)
you can achieve this with help of Protocol
protocol common {
static func doSomething()
}
class Foo : common{
static func doSomething() {
print("Foo")
}
}
class Foobar : common {
static func doSomething() {
print("Foobar")
}
}
class ActualWork{
//call following method with a variable type so that it accepts dynamic class name
func callDynamicClassMethod(x: common.Type) {
x.doSomething()
}
}
let fooObj : common = Foo()
let Foobarobj : common = Foobar()
let workObk = ActualWork()
workObk.callDynamicClassMethod(x:Foo.self)
workObk.callDynamicClassMethod(x:Foobar.self)
I think, there are three solutions. I shared an sample below.
Use "protocol" that has "doSomething()" function requirements.
Create a function which gets function definition as a parameter.
Use reflection. you can use EVReflection that is good Api for reflection.
sample code:
protocol FooProtocol {
static func doSomething()
}
class Foo: FooProtocol {
class func doSomething() {
print("Foo:doSomething")
}
}
class Foobar: FooProtocol {
class func doSomething() {
print("Foobar:doSomething")
}
}
class ActualWork {
func callDynamicClassMethod<T: FooProtocol>(x: T.Type) {
x.doSomething()
}
func callDynamicClassMethod(x: #autoclosure () -> Void) {
x()
}
func callDynamicClassMethod(x: () -> Void) {
x()
}
}
ActualWork().callDynamicClassMethod(x: Foo.self)
ActualWork().callDynamicClassMethod(x: Foobar.self)
print("\n")
ActualWork().callDynamicClassMethod(x: Foo.doSomething())
ActualWork().callDynamicClassMethod(x: Foobar.doSomething())
print("\n")
ActualWork().callDynamicClassMethod(x: Foo.doSomething)
ActualWork().callDynamicClassMethod(x: Foobar.doSomething)
Looks like you are searching for duck typing, and this is harder to achieve in a statically typed language (with some exceptions, listed in the linked Wikipedia page).
This is because dynamically calling a method requires knowledge about the layout of the target object, thus either inheritance of the class declaring the method, or conformance to a protocol that requires that method.
Starting with Swift 4.2, and the introduction of dynamic member lookup, there is another approach to solve your problem, however it also involves some ceremony:
// This needs to be used as base of all classes that you want to pass
// as arguments
#dynamicMemberLookup
class BaseDynamicClass {
subscript(dynamicMember member: String) -> () -> Void {
return { /* empty closure do nothing */ }
}
}
// subclasses can choose to respond to member queries any way they like
class Foo: BaseDynamicClass {
override subscript(dynamicMember member: String) -> () -> Void {
if member == "doSomething" { return doSomething }
return super[dynamicMember: member]
}
func doSomething() {
print("Dynamic from Foo")
}
}
class Bar: BaseDynamicClass {
override subscript(dynamicMember member: String) -> () -> Void {
if member == "doSomething" { return doSomething }
return super[dynamicMember: member]
}
func doSomething() {
print("Dynamic from Bar")
}
}
func test(receiver: BaseDynamicClass) {
receiver.doSomething()
}
test(receiver: Bar()) // Dynamic from Bar
To conclude, in the current Swift version there is no way to have both the argument and the method dynamic, some common ground needs to be set.

Resources