3 added example demonstrating OP's original scenario where Service has dependencies provided via DI along with dependencies provided by client.
source | link

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.

The factories can be very simple and also allow you to avoid init() methods and use constructors instead:

public interface IServiceFactory
{
    IService createService(Context context);
}

public class ServiceFactory : IServiceFactory
{
    public Service createService(Context context)
    {
        return new Service(context);
    }
}

In the client, OnStartup() is also an initialization method (it just uses a different name). So if possible (if you know the Context data), the factory should directly be called in the Client constructor. If that's not possible, you need to store the IServiceFactory and call it in OnStartup().

When Service has dependencies not provided by Client they would be provided by DI through ServiceFactory:

public interface IServiceFactory
{
    IService createService(Context context);
}    

public class ServiceFactory : IServiceFactory
{        
    private readonly object dependency1;
    private readonly object dependency2;
    private readonly object dependency3;

    public ServiceFactory(object dependency1, object dependency2, object dependency3)
    {
        this.dependency1 = dependency1;
        this.dependency2 = dependency2;
        this.dependency3 = dependency3;
    }

    public Service createService(Context context)
    {
        return new Service(context, dependency1, dependency2, dependency3);
    }
}

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.

The factories can be very simple and also allow you to avoid init() methods and use constructors instead:

public interface IServiceFactory
{
    IService createService(Context context);
}

public class ServiceFactory : IServiceFactory
{
    public Service createService(Context context)
    {
        return new Service(context);
    }
}

In the client, OnStartup() is also an initialization method (it just uses a different name). So if possible (if you know the Context data), the factory should directly be called in the Client constructor. If that's not possible, you need to store the IServiceFactory and call it in OnStartup().

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.

The factories can be very simple and also allow you to avoid init() methods and use constructors instead:

public interface IServiceFactory
{
    IService createService(Context context);
}

public class ServiceFactory : IServiceFactory
{
    public Service createService(Context context)
    {
        return new Service(context);
    }
}

In the client, OnStartup() is also an initialization method (it just uses a different name). So if possible (if you know the Context data), the factory should directly be called in the Client constructor. If that's not possible, you need to store the IServiceFactory and call it in OnStartup().

When Service has dependencies not provided by Client they would be provided by DI through ServiceFactory:

public interface IServiceFactory
{
    IService createService(Context context);
}    

public class ServiceFactory : IServiceFactory
{        
    private readonly object dependency1;
    private readonly object dependency2;
    private readonly object dependency3;

    public ServiceFactory(object dependency1, object dependency2, object dependency3)
    {
        this.dependency1 = dependency1;
        this.dependency2 = dependency2;
        this.dependency3 = dependency3;
    }

    public Service createService(Context context)
    {
        return new Service(context, dependency1, dependency2, dependency3);
    }
}
2 added 705 characters in body
source | link

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.

The factories can be very simple and also allow you to avoid init() methods and use constructors instead:

public interface IServiceFactory
{
    IService createService(Context context);
}

public class ServiceFactory : IServiceFactory
{
    public Service createService(Context context)
    {
        return new Service(context);
    }
}

In the client, OnStartup() is also an initialization method (it just uses a different name). So if possible (if you know the Context data), the factory should directly be called in the Client constructor. If that's not possible, you need to store the IServiceFactory and call it in OnStartup().

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.

The factories can be very simple and also allow you to avoid init() methods and use constructors instead:

public interface IServiceFactory
{
    IService createService(Context context);
}

public class ServiceFactory : IServiceFactory
{
    public Service createService(Context context)
    {
        return new Service(context);
    }
}

In the client, OnStartup() is also an initialization method (it just uses a different name). So if possible (if you know the Context data), the factory should directly be called in the Client constructor. If that's not possible, you need to store the IServiceFactory and call it in OnStartup().

1
source | link

There are several ways to deal with the initialization problem:

  • As answered in https://softwareengineering.stackexchange.com/a/334994/301401, init() methods are a code smell. Initializing an object is the responsibility of the constructor - that's why we have constructors after all.
  • Add The given service must be initialized to the doc comment of Client constructor and let the constructor throw if the service is not initialized. This moves the responsibility to the one who gives you the IService object.

However, in your example, the Client is the only one that knows the values that are passed to Initialize(). If you want to keep it that way, I'd suggest the following:

  • Add an IServiceFactory and pass it to the Client constructor. Then you can call serviceFactory.createService(new Context(...)) which gives you an initialized IService that can be used by your client.