简体   繁体   中英

How to overload generic C# methods in Factory?

I want to create something like a factory, but it 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 into my implementation two different services which implement two different interfaces. Let think 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's not an overloaded method
    }
}

How to create the SecondService in this way? I know that my question and my code example is terrible and this is an improper approach, but want to know what other developers do in this case. Thanks.

The simplest solution to your problem might be to avoid overloading the factory method completely (not very 'OO' though). Examine the generic type parameter, create the appropriate instance, and cast it back 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");
        }
}

Currently, the contract of IServiceFactory specifies that any service can be created. Your concrete implementation, however, only provides two specific services. Thus, you did not implement the interface contract.

How do we fix this? By changing the implementation (so that any service can be created) or by changing the contract (so that only the two given 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 for that. Additional bonus: If the first and the second service require different parameters, your can support that, too.

The FirstService und SeconService should extend a common Interface (eg their Interfaces extend a common Interface like ServiceInterface, or they extend directly from some common Interface like ServiceInterface) For concrete creation you would pass the wished concrete type (or a string...) to the create method of the 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)
        }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM