Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No "ToTransientMethod" method in BinderUntyped #46

Closed
cgarciae opened this issue Aug 19, 2015 · 9 comments
Closed

No "ToTransientMethod" method in BinderUntyped #46

cgarciae opened this issue Aug 19, 2015 · 9 comments

Comments

@cgarciae
Copy link

Currently there is only a ToSingleMethod but I specifically need the dependency to be transient. Can this method be added to Zenject? I am trying to do the same as yesterday but now by passing types as parameters

        public static void ToPrefab(this BinderUntyped binder, String prefabLocation, Type type)
        {
            //NEED TRANSIENT VERSION
            binder.ToSingleMethod((ctx) => {
                var obj = Resources.Load(prefabLocation) as GameObject;
                return ctx.Container.InstantiatePrefabForComponent(type, obj) as MonoBehaviour;
            });
        }
@svermeulen
Copy link

You can just use ToMethod instead, which is transient.

@svermeulen
Copy link

Oh wait, you're right, only BinderGeneric has ToMethod surprisingly. I'll fix that.

@cgarciae
Copy link
Author

@svermeulen Thanks! I looked at the code inside BinderUntyped and there only seem to be singleton methods so the fix doesn't look that simple.

@svermeulen
Copy link

Ok I pushed a change that adds that method. I tested it in the unit tests but will wait to hear from you whether that solves your problem before closing this item

@cgarciae
Copy link
Author

I am having a small problem that didn't happen in ToSingleMethod, in the new extension method

        public static void ToPrefab(this BinderUntyped binder, String prefabLocation, Type type)
        {
            binder.ToMethod((ctx) => {
                var obj = Resources.Load(prefabLocation) as GameObject;
                return ctx.Container.InstantiatePrefabForComponent(type, obj) as MonoBehaviour;
            });
        }

TContract in ToMethod<TContract> gets set as MonoBehaviour because its the only sensible type I can cast to. However, the actual type of obj is type (obj.GetType() == type) and that type is known to extend MonoBehaviour.

So Zenject complains

ZenjectBindException: Invalid type given during bind command. Expected type 'UnityEngine.MonoBehaviour' to derive from type

I actually commented your code (the part that check types) so it didn't throw that exception but I got

ZenjectException: Assert hit!
ModestTree.Assert.Throw (System.String message) (at Assets/Lib/Zenject/Internal/Assert.cs:195)
ModestTree.Assert.That (Boolean condition) (at Assets/Lib/Zenject/Internal/Assert.cs:29)
Zenject.MethodProvider`1[UnityEngine.MonoBehaviour].GetInstance (Zenject.InjectContext context) (at Assets/Lib/Zenject/Main/Scripts/Providers/MethodProvider.cs:25)
Zenject.DiContainer.Resolve (Zenject.InjectContext context) (at Assets/Lib/Zenject/Main/Scripts/Main/DiContainer.cs:578)
Zenject.DiContainer.Resolve (System.Type contractType) (at Assets/Lib/Zenject/Main/Scripts/Main/DiContainer.cs:1175)

I actually need something that binds the method type as a parameter like this

        public static void ToPrefab(this BinderUntyped binder, String prefabLocation, Type type)
        {
            //Pass "type" into ToMethod
            binder.ToMethod(type, (ctx) => {
                var obj = Resources.Load(prefabLocation) as GameObject;
                return ctx.Container.InstantiatePrefabForComponent(type, obj) as MonoBehaviour;
            });
        }

@cgarciae
Copy link
Author

If passing type as a parameter is not possible, is the exception I get when I comment your code due to the same exception as yesterday (something about not having a CompositionRoot)?

@svermeulen
Copy link

Ok I added a non-generic version of ToMethod, try that. What errors are you getting now?

@cgarciae
Copy link
Author

Works!!!!!!!!!!!!!!!!!!!!!!!!

Thanks man. Now I am able to define Routes like this with my framework

    [Route("some/route")]
    public class SomeRouteView : MonoBehaviour
    {
        [PostInject]
        public void PostConstruct(...) {
            ...
        }
    }

and start and configure like this

    public class Startup : MVCApp
    {
        public override void Configure(IApplication app, DiContainer container)
        {
            //Set view dependencies
        }

        public override void Init(IRouter router)
        {
            router.GoTo(
                url: "some/view",
                body: 42
            );
        }
    }

the framework looks for classes annotated with Route and wires the dependencies with your code!!!

@svermeulen
Copy link

Ok great :)

Sounds like a cool setup

yonkahlon pushed a commit to yonkahlon/Zenject that referenced this issue Apr 23, 2017
yonkahlon pushed a commit to yonkahlon/Zenject that referenced this issue Apr 23, 2017
JamesKim2998 pushed a commit to devsisters/Zenject that referenced this issue Dec 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants