我可以重构具有相似输入但将不同服务调用为一个通用函数的函数吗?

时间:2019-03-28 16:38:25

标签: c# generics design-patterns asp.net-web-api2 refactoring

我正在寻找一种将x个非常相似的CRUD函数合并为一个的方法,而不必使用x个if语句来检查泛型的类型。

我有一些Web API控制器,我想从中进行调用:

Service.Get<FooModel>(number, type, part, version); 

这是为了避免必须对40多个API端点具有极其相似的功能。问题是,当我在服务中收到此消息时,我必须检查给定泛型的类型,并与一个函数中的40多个对象类型进行比较。当前,所有模型都从基本继承的模型继承。

当前通用函数

(创建,更新,删除功能相似):

public T Get<T>(string documentNr, string type, string part, string version) where T : InheritedModel, new()
{
    try
    {
        T model = new T();

        if (typeof(T) == typeof(InheritedModel))
        {
           using (var repo = new InheritedModelConsumer(ref _helper))
           {
                model = (T)repo.Get(documentNr, type, part, version);
           }
        }
        else if (typeof(T) == typeof(FooModel))
        {
            using (var repo = new FooModelConsumer(ref _helper))
            {
                model = (T)(object)repo.Get(documentNr, type, part, version);
            }
        }
        else if (typeof(T) == typeof(ComponentModel))
        {
            using (var repo = new ComponentModelConsumer(ref _helper))
            {
                model = (T)(object)repo.Get(documentNr, type, part, version);
            }
        }
        else if (typeof(T) == typeof(BarModel))
        {
            using (var repo = new BarModelConsumer(ref _helper))
            {
               model = (T)(object)repo.Get(documentNr, type, part, version);
            }
        }
        ... and so on
        ... and so on
        ...
        else
            throw new Exception("Type T structure not defined");

        return model;
    }
    catch (Exception)
    {

        throw;
    }
    finally
    {
        _helper.Dispose();
    }
}

这确实有效,但是如果可能的话,我正在寻找可以在运行时说的内容,“哦,我有T型对象,而且由于我知道所有函数都具有相同的输入,将实例化此TConsumer类型的使用者,调用Consumer.Get(inputs),然后将T的对象返回给任何称为我的API控制器。”

编辑

正在使用的简单消费者类的示例


    internal sealed class FooConsumer : RepositoryConsumer<Foo, FooRepository, FooFilter>
        {
            public FooConsumer(ref SqlHelper helper) : base(ref helper) { }

            public List<Foo> GetAll(string token)
            {
                return _repo.Get().Where(x => Extensions.StringContainsToken(x.AccountName, token)).ToList();
            }
        }

存储库使用者,所有使用者都继承自。 T是模型,K是存储库(自定义ORM类),O是ORM执行的WHERE子句的Filter。



     public abstract class RepositoryConsumer<T, K, O> : IDisposable, IRepositoryConsumer<T> where T : class, new() where K : Repository<T, O>, new() where O : QueryFilter, new()
        {
            /// <summary>
            /// Repository instance
            /// </summary>
            protected K _repo;

            /// <summary>
            /// Only constructor avaialble. MUst pass SqlHelper instance for transaction support
            /// </summary>
            /// <param name="sql"></param>
            public RepositoryConsumer(ref SqlHelper sql)
            {
                _repo = Activator.CreateInstance(typeof(K), new object[] { sql }) as K;
            }

            /// <summary>
            /// Allow consumer initializations in using statements
            /// </summary>
            public void Dispose()
            {

            }

            /// <summary>
            /// Create instance of T
            /// </summary>
            /// <param name="data"></param>
            /// <returns></returns>
            public virtual int Create(T data)
            {
                return _repo.Create(data);
            }

            /// <summary>
            /// Bulk create instances of T
            /// </summary>
            /// <param name="contract"></param>
            /// <returns></returns>
            public virtual int Create(BaseBulkable<T> contract)
            {
                return _repo.BulkCreate(contract);
            }

            /// <summary>
            /// Get an instance of T based on a single PK field id
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public virtual T Get(long id)
            {
                return _repo.Get(id);
            }

            /// <summary>
            /// Gets all instances of T
            /// </summary>
            /// <returns></returns>
            public virtual List<T> GetAll()
            {
                return _repo.Get();
            }

            /// <summary>
            /// Updates an instance of T
            /// </summary>
            /// <param name="data"></param>
            /// <returns></returns>
            public virtual int Update(T data)
            {
                return _repo.Update(data);
            }

            /// <summary>
            /// Updates an instance of T based on a single PK field id
            /// </summary>
            /// <param name="id"></param>
            /// <param name="data"></param>
            /// <returns></returns>
            public virtual int Update(long id, T data)
            {
                return _repo.Update(id, data);
            }

            /// <summary>
            /// Deletes an instance of T
            /// </summary>
            /// <param name="data"></param>
            /// <returns></returns>
            public virtual int Delete(T data)
            {
                return _repo.Delete(data);
            }

            /// <summary>
            /// Deletes an instance of T based on a single PK field id
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public virtual int Delete(long id)
            {
                return _repo.Delete(id);
            }
        }

0 个答案:

没有答案