Search code examples
c#wpfmvvmprism

RegisterSingleton with constructor parameter


I have a service called CustomerService, in a separate DLL project, and this service needs a connection string from App.config in the main project. This is the CustomerService:

public class CustomerService : ICustomerService
{
    private string _mySQLConnectionString;

    public CustomerService(string mySQLConnectionString)
    {
        _mySQLConnectionString = mySQLConnectionString;
    }

    public List<Customer> GetCustomerList()
    {
        return new List<Customer>();
    }
}

I want to register this service with containerRegistry.RegisterSingleton as follows. How can I add the constructor parameter? Is there any other solution to share the connection string from the App.config with multiple services in separate DLL projects.

public void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterSingleton<ICustomerService, CustomerService>();
}

Note: Connection string needed for multiple services to connect a MySQL server.

Question part two: How can I register another singleton call it "service" (example: SocketService) and share that singleton with other registered singletons, for example my CustomerService or ItemService? So all registered "services" can call the Connect() method from the SocketService.


Solution

  • You can create an instance of the type first and call RegisterInstance.

    var mySQLConnectionString = "...";
    var customerService = new CustomerService(mySQLConnectionString);
    containerRegistry.RegisterInstance(customerService);
    

    An alternative is to use a factory method instead, provided on an overload of RegisterSingleton.

    var mySQLConnectionString = "...";
    containerRegistry.RegisterSingleton<CustomerService>(() => new CustomerService(mySQLConnectionString));
    

    If you need even more flexibility, e.g. resolving other types, use another overload with the container.

    containerRegistry.RegisterSingleton<AnyService>(containerProvider =>
    {
       var anyOtherService = containerProvider.Resolve<AnyOtherService>();
       // ...other complex setups
       return new AnyService(anyOtherService);
    });
    

    How can I register another singleton call it "service" (example: SocketService) and share that singleton for other registered singletons for example my CustomerService or ItemService? So all registered "service" can call the my Connect() method from the SocketService.

    Specify the dependencies as constructor parameters in your CustomerService (ideally with interfaces to ease unit testing) and register it and its dependencies to the container.

    public class CustomerService : ICustomerService
    {
        private string _mySQLConnectionString;
    
        public CustomerService(string mySQLConnectionString, ISocketService socketService)
        {
            _mySQLConnectionString = mySQLConnectionString;
            // ...other code.
        }
        
        // ...other code.
    }
    
    var mySQLConnectionString = "...";
    
    containerRegistry.RegisterSingleton<ISocketService, SocketService>();
    containerRegistry.RegisterSingleton<CustomerService>(containerProvider =>
    {
       var sockertService = containerProvider.Resolve<SocketService>();
       // ...other complex setups
       return new CustomerService(mySQLConnectionString, sockertService);
    });
    

    Once you resolve any of these types, the container will take care of setting up the dependencies.