Search code examples
xamarin.formsprismcsla

Prism for Xamarin.Forms with Unity and CSLA


I'm currently working on a Xamarin.Forms application using Prism and Unity as my IoC container.

I'm also attempting to add the business logic framework CSLA to my application.

There is a Xamarin sample provided here:

https://github.com/MarimerLLC/csla/blob/main/Samples/XamarinExample/XamarinExample/XamarinExample/App.xaml.cs

In particular, everything seems to be wired up using this piece of code:

public App()
{
      InitializeComponent();

      var services = new ServiceCollection();
      services.AddCsla();

      services.AddTransient(typeof(DataAccess.IPersonDal), typeof(DataAccess.PersonDal));
      serviceProvider = services.BuildServiceProvider();
      ApplicationContext = serviceProvider.GetRequiredService<ApplicationContext>();

      MainPage = new AppShell();
}

I'm trying to figure out how to fit that sort of code / registration into the Prism framework with Unity as the IoC container. Is this a time when I'd need to use the extensions? I saw those, but I was still coming up a little short on understanding what I should be doing.

I feel like there's a fundamental misunderstanding on my part of what I should be trying to achieve here, so any guidance on what direction I should be going in would be great.


Solution

  • I think this may be what I'm looking for:

       protected override IContainerExtension CreateContainerExtension() {
            var containerExtension = base.CreateContainerExtension();
        
            var services = new ServiceCollection();
    
            services.AddCsla();
            
            var serviceProvider = ((UnityContainerExtension)containerExtension).Instance.BuildServiceProvider(services);
    
            ApplicationContext = serviceProvider.GetRequiredService<ApplicationContext>();
    
            return containerExtension;
        }
    

    Basically, it seems that I can override the container creation in my app.cs. From there I can call whatever methods I'd like against the ServiceCollection, build the container using the extension (in this case Unity) and return that container to the application.

    Testing this in code I can see that I'm now able to inject the IDataPortalFactory into my view model along with the IServiceProvider, and the IServiceProvider is of type Unity.Microsoft.DependencyInjection.ServiceProvider.

        public MainPageViewModel(
            INavigationService navigationService, 
            IServiceProvider serviceProvider, 
            IDataPortalFactory dataPortalFactory, 
            ITestClassFactory testClassFactory)
            : base(navigationService) {
            Title = "Main Page";
    
            this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
            this.dataPortalFactory = dataPortalFactory ?? throw new ArgumentNullException(nameof(dataPortalFactory));
            this.testClassFactory = testClassFactory ?? throw new ArgumentNullException(nameof(testClassFactory));
        }
    

    So, if I'm getting IDataPortalFactory in my view model, I'm assuming my call to AddCsla() worked, and if the IServiceProvider is considered to be a Unity service provider, I must have successfully replaced the Service Provider implementation.