2015-12-15 2 views
1

Мне нужно сделать общие методы для моих сервисов и использовать репозиторий или другое в зависимости от типа объекта, который я передаю как аргумент.Использование общих классов с впрыском зависимостей с C#

К примеру, у меня есть эти интерфейсы:

public interface IServiceText 
{ 
    Task<string> UpdateTextPosition(TextDto object); 
    Task<string> UpdateTextSize(TextDto object); 
    Task<string> UpdateOtherThingOnText(TextDto object); 

} 

public interface IServiceImage 
{ 
    Task<string> UpdateImagePosition(ImageDto object); 
    Task<string> UpdateImageSize(ImageDto object); 
    Task<string> UpdateOtherThingOnImage(ImageDto object); 

} 

В руке порядка, у меня есть классы, которые реализуют интерфейсы (добавлены только важный код) и с конструкторами:

//Class ServiceImage 
private readonly IRepository<Image> _repo; 

public ServiceImage(IRepository<Image> repo) //Dependecy Injection of the IRepository Generic 
{ 
    _repo = repo; 
} 

//Class ServiceText 
private readonly IRepository<Text> _repo; 

public ServiceText(IRepository<Text> repo) //Dependecy Injection of the IRepository Generic 
{ 
    _repo = repo; 
} 

UpdateTextPosition и UpdateImagePosition выполняют точно то же самое, но в разных сборниках (или используя разные экземпляры IRepository, я использую MongoDB):

public async Task<string> UpdateTextPosition(TextDto object) 
{ 
    var text = await _repo.FindAsync(object.Id); 
    text.PosLeft = object.PosLef; 
    text.PosRight = object.PosRight; 
    await _repo.Update(text); 
    return text.Id; 

} 

public async Task<string> UpdateImagePosition(ImageDto object) 
{ 
    var image = await _repo.FindAsync(object.Id); 
    image.PosLeft = object.PosLef; 
    image.PosRight = object.PosRight; 
    await _repo.Update(image); 
    return image.Id 

} 

EDIT: (добавлено ImageDto и TextDto)

public class ImageDto 
{ 
    public ObjectId Id {get; set;} 
    public int PosLeft {get; set;} 
    public int PosTop {get; set;} 
    public ICollection<string> PropertyImage1 {get; set;} 
    public string PropertyImage2 {get; set;} 
} 


public class TextDto 
{ 
    public ObjectId Id {get; set;} 
    public int PosLeft {get; set;} 
    public int PosTop {get; set;} 
    public double PropertyText1 {get; set;} 
    public string PropertyText2 {get; set;} 
} 

public class Image : Entity 
    { 
     public ObjectId Id {get; set;} 
     public int PosLeft {get; set;} 
     public int PosTop {get; set;} 
     public ICollection<string> PropertyImage1 {get; set;} 
     public string PropertyImage2 {get; set;} 
     public string OtherPropertyImage {get; set;} 
    } 


public class Text : Entity 
{ 
    public ObjectId Id {get; set;} 
    public int PosLeft {get; set;} 
    public int PosTop {get; set;} 
    public double PropertyText1 {get; set;} 
    public string PropertyText2 {get; set;} 
    public string OtherPropertyText {get; set;} 
} 

И IEntity:

/// <summary> 
/// Generic Entity interface. 
/// </summary> 
/// <typeparam name="TKey">The type used for the entity's Id.</typeparam> 
public interface IEntity<TKey> 
{ 
    /// <summary> 
    /// Gets or sets the Id of the Entity. 
    /// </summary> 
    /// <value>Id of the Entity.</value> 
    [BsonId] 
    TKey Id { get; set; } 
} 

/// <summary> 
/// "Default" Entity interface. 
/// </summary> 
/// <remarks>Entities are assumed to use strings for Id's.</remarks> 
public interface IEntity : IEntity<string> 
{ 
} 

И класс Entity:

/// <summary> 
    /// Abstract Entity for all the BusinessEntities. 
    /// </summary> 
    //[DataContract] 
    [Serializable] 
    [BsonIgnoreExtraElements(Inherited = true)] 
    public abstract class Entity : IEntity<string> 
    { 
     /// <summary> 
     /// Gets or sets the id for this object (the primary record for an entity). 
     /// </summary> 
     /// <value>The id for this object (the primary record for an entity).</value> 
     [DataMember] 
     [BsonRepresentation(BsonType.ObjectId)] 
     public virtual string Id { get; set; } 
    } 

мне нужнопереместите «общие методы» в новый CommonService с интерфейсом (ICommonService), и возьмите тип объекта и определите, что использует IMongoRepository ... Я думаю, что Generic - это мой способ ... но я прочитал об этом , но я не очень хорошо понимаю примеры, и я хотел бы наилучшим образом реализовать это в своем реальном решении.

Thank you soooo много !!

+0

Другие методы также выглядят одинаково (например, «UpdateOtherThingOnText» и «UpdateOtherThingOnImage»)? или только методы, которые вы предоставили? Можете ли вы показать определение 'ImageDto' и' TextDto'? –

+0

@YacoubMassad Привет!Я добавил класс ImageDto и TextDto :) Nop, другие методы совершенно разные. – chemitaxis

+0

Итак, вы хотите создать службу, которая имеет один метод, называемый «UpdatePosition», который работает как на «ImageDto», так и «TextDto» и, возможно, на других DTO, не так ли? –

ответ

1

Если я правильно понял ваш вопрос, то вы должны сделать что-то, что выглядит следующим образом:

Сначала создайте общий интерфейс для ваших DTOS:

public interface IDtoCommon 
{ 
    ObjectId Id { get; set; } 
    int PosLeft { get; set; } 
    int PosTop { get; set; } 
} 

И общий интерфейс для ваших сущностей:

public interface IEntityCommon 
{ 
    ObjectId Id { get; set; } 
    int PosLeft { get; set; } 
    int PosTop { get; set; } 
} 

Так вот как ваши DTOS и юридические лица будут выглядеть следующим образом:

public class ImageDto : IDtoCommon 
{ 
    public ObjectId Id {get; set;} 
    public int PosLeft {get; set;} 
    public int PosTop {get; set;} 
    public ICollection<string> PropertyImage1 {get; set;} 
    public string PropertyImage2 {get; set;} 
} 


public class TextDto : IDtoCommon 
{ 
    public ObjectId Id {get; set;} 
    public int PosLeft {get; set;} 
    public int PosTop {get; set;} 
    public double PropertyText1 {get; set;} 
    public string PropertyText2 {get; set;} 
} 

public class Image : Entity, IEntityCommon 
{ 
    public ObjectId Id { get; set; } 
    public int PosLeft { get; set; } 
    public int PosTop { get; set; } 
    public ICollection<string> PropertyImage1 { get; set; } 
    public string PropertyImage2 { get; set; } 
    public string OtherPropertyImage { get; set; } 
} 

public class Text : Entity, IEntityCommon 
{ 
    public ObjectId Id { get; set; } 
    public int PosLeft { get; set; } 
    public int PosTop { get; set; } 
    public double PropertyText1 { get; set; } 
    public string PropertyText2 { get; set; } 
    public string OtherPropertyText { get; set; } 
} 

А вот как ваша общая служба будет выглядеть следующим образом:

public interface ICommonService<TDto> where TDto : IDtoCommon 
{ 
    Task<string> UpdatePosition(TDto @object); 
} 

public class CommonService<TDto, TEntity> : ICommonService<TDto> 
    where TDto : IDtoCommon 
    where TEntity : IEntityCommon 
{ 
    private readonly IRepository<TEntity> m_Repository; 

    public CommonService(IRepository<TEntity> repository) 
    { 
     m_Repository = repository; 
    } 

    public async Task<string> UpdatePosition(TDto @object) 
    { 
     var entity = await m_Repository.FindAsync(@object.Id); 
     entity.PosLeft = @object.PosLeft; 
     entity.PosTop = @object.PosTop; 
     await m_Repository.Update(entity); 
     return entity.Id.Value; 
    } 
} 

А вот пример того, как он может быть использован:

CommonService<TextDto, Text> service = new CommonService<TextDto, Text>(new Repository<Text>()); 

service.UpdatePosition(text_dto); 

Вы должны думать о том, есть ли у Вас достаточно повторения в вашем коде, чтобы оправдать все это.

+0

Привет! Ваш ответ потрясающий, большое вам спасибо за ваше время. Я думаю, что это хороший пример для других разработчиков ... Я беспокоюсь о производительности ... Как вы думаете? Вы говорите «думая об этом решении» ... Можете ли вы рассказать ссылку, чтобы решить, какое решение лучше? Повторите или общие классы? – chemitaxis

+2

Я не думаю, что проблема с производительностью. Мое замечание было о том, сколько повторений это решение спасет вас? Вы должны решить, используете ли вы меньшее количество кода, используя это решение. Сохраняет ли он больше строк кода, чем строки добавленного кода (и сложность, которую он добавляет)? –

+0

Мы говорим о 6 методах и 5 объектах ... Как вы думаете? :) – chemitaxis

Смежные вопросы