How to overload C # generic methods in Factory?

I want to create something like a factory, but this is not an implementation of the factory pattern.

I have an IServiceFactory interface :

public interface IServiceFactory
{
    TServiceInterface CreateService<TServiceInterface>(string url);
}

      

I want to create in my implementation two different services that implement two different interfaces. Let me think that I have:

public class FirstService : IFirstService {}
public class SecondService : ISecondService {}

public class ServiceFactory : IServiceFactory
{
    public IFirstService CreateService<IFirstService>(string url)
    {
        // logic of creation
    }

    public ISecondService CreateService<ISecondService>(string url)
    {
        // Unforchantly, it not an overloaded method
    }
}

      

How to create SecondService

this way? I know my question and my sample code are terrible and this is the wrong approach, but you want to know what other developers are doing in this case. Thank you.

+3


source to share


3 answers


The simplest solution to your problem might be to completely overload the factory method (not really "OO"). Examine the type parameter, instantiate it appropriately and return it to the correct type:



public class ServiceFactory : IServiceFactory {
    public TServiceType CreateService<TServiceType>(string url)
        {
            Type t = typeof(TServiceType);

            if (t == typeof(IFirstService))
                return (TServiceType) CreateFirstServiceInstance(url);

            if (t == typeof(ISecondService))
                return (TServiceType) CreateSecondServiceInstance(url);

            throw new InvalidOperationException("Unsupported service type");
        }
}

      

+1


source


Currently, the contract IServiceFactory

indicates that it can be created either . However, your specific implementation only provides two specific services. So you haven't implemented the interface contract.

How do we fix this? By modifying the implementation (so that any service can be created) or by modifying the contract (so that only the two specified services can be created). The answer from richzilla gives an example for the former, here is an example for the latter:



public interface IServiceFactory
{
    IFirstService CreateFirstService(string url);
    ISecondService CreateSecondService(string url);
}

public class ServiceFactory : IServiceFactory
{
    public IFirstService CreateFirstService(string url) { ... }
    public ISecondService CreateSecondService(string url) { ... }
}

      

You don't even need generics. Added bonus: If the first and second services require different parameters, you can support that too.

+1


source


FirstService und SeconService must extend a common interface (for example, their interfaces extend a common interface like ServiceInterface, or extend directly from some common interface like ServiceInterface) For a concrete creation, you must pass the desired concrete type (or string ...) to the method creating a factory:

public interface IService {}
public interface IFirstService : IService {}
public interface ISecondService : IService {}
public class FirstService : IFirstService {}
public class SecondService : ISecondService {}

public class ServiceFactory : IServiceFactory {
    public IService CreateService<IService>(Type class, string url)
        {
            // logic of creation
            new class(url)
        }
}

      

+1


source







All Articles