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

Standard way to initialize required internal framework properties beside normal startup & testing; e.g. for WPF design-mode support #3133

Open
7 tasks done
HaraldMuehlhoffCC opened this issue Sep 27, 2018 · 4 comments
Labels
t/feature Feature request type up-for-grabs Issues up for grabs by anyone

Comments

@HaraldMuehlhoffCC
Copy link
Contributor

🏗 Enhancement Proposal

A few months ago I implemented Design-Mode-Support for our application; the views are WPF & the XAML designer supports design mode for views with a special d:DataContext="{d:DesignInstance vm:MenuViewModel, IsDesignTimeCreatable=True}" attribute so the WPF controls in the XAML preview in Visual Studio are already populated with some sample data to make designing & coding easier. I had to create some rudimentary design mode support for the ViewModel (like constructors without arguments; a little design time DI support) but nothing too tricky.
With the recent MvvmCross update this broke because a Trace extension method failed as a side effect to a property change somewhere deep in the framework; the MvxLog.Instance was null.

I looked for places in the source where MvxLog.Instance is already being initialized and this is during normal application startup (MvxSetup) and in some helper for testing (MvxIocSupportingTest).

So I did the same in my InitializeDesignTimeIoCContainer method but I had to use reflection because the MvxLog class is internal as is the static Instance property. Otherwise it's pretty similar to the code found inside MvvmCross.

    [DesignModeOnly]
    static public void InitializeDesignTimeIoCContainer()
    {
        EnforceDesignMode();

        var iocProvider = MvxIoCProvider.Initialize();
        Mvx.IoCProvider.RegisterSingleton(iocProvider);

        // Access internal class MvxLog
        var mvxLogClass = typeof(MvxLogExtensions).Assembly.GetType("MvvmCross.Logging.MvxLog");
        var globalLog = new DesignModeLogProvider().GetLogFor(mvxLogClass);

        // Set static Instance property of MvxLog to globalLog
        PropertyInfo propInfo = mvxLogClass.GetProperty("Instance", BindingFlags.Static | BindingFlags.NonPublic);
        propInfo.SetValue(mvxLogClass, globalLog);

        Mvx.IoCProvider.RegisterSingleton(globalLog);

        Mvx.IoCProvider.RegisterSingleton<IFMModuleService>(() => new FMModuleServiceMock());
    }

Now my design mode support is working again - until the next change...

I understand that this currently isn't a supported scenario so I didn't file this issue as a regression.
Nevertheless here is a real need & my colleagues are enjoying the design time feature so I don't want it to go away.

Some official way to initialize MvxLog.Instance - or better all required internal "properties" - for cases like mine would be very much appreciated.

I'd work on a PR but some guidance would be required.

Pitch

Beside normal application startup there is already a need when it comes to testing to initialize properties in internal classes like MvxLog.Instance. It would be great if a more general solution would be available, e.g. for design time support as explained above. At least there should be a way to initialize the required classes so that no reflection has to be used.

Platforms affected (mark all that apply)

  • 📱 iOS
  • 🤖 Android
  • 🏁 WPF
  • 🌎 UWP
  • 🍎 MacOS
  • 📺 tvOS
  • 🐒 Xamarin.Forms
@Cheesebaron
Copy link
Member

Cheesebaron commented Sep 27, 2018

This sounds kind of what we are doing for our UnitTests: https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross.Tests/MvxIoCSupportingTest.cs

GitHub
The .NET MVVM framework for cross-platform solutions, including Xamarin.iOS, Xamarin.Android, Windows and Mac. - MvvmCross/MvvmCross

@Cheesebaron Cheesebaron added t/feature Feature request type up-for-grabs Issues up for grabs by anyone labels Sep 27, 2018
@HaraldMuehlhoffCC
Copy link
Contributor Author

HaraldMuehlhoffCC commented Sep 27, 2018

@Cheesebaron Exactly! (BTW - I mentioned the class in my - pretty long - proposal ;) )

I could imagine some public class that can be used to perform basic initialization - either generally or just for special purposes like design-time support (or testing …).
Some guidance / ideas as how to best integrate this into the large MvvmCross puzzle would be very much appreciated!

A much simpler idea ... One might add lazy initialization to MvxLog.Instance; it might try to get an instance via DI. What do you think of this?

@Cheesebaron
Copy link
Member

I think this is vote number 2 for making MvxLog not internal. Alternatively as you say we should provide a Design Time helper, which helps setting up all the necessary stuff, similar to what we do in our Tests.

@martijn00, @nickrandolph what do you think?

@rodrigojuarez
Copy link

Any news about this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
t/feature Feature request type up-for-grabs Issues up for grabs by anyone
Development

No branches or pull requests

3 participants