Префикс пространства имен интерфейса c # - PullRequest
1 голос
/ 10 марта 2011

Предположим, у меня есть этот интерфейс IRepository

 public interface IRepository
 {
    #region User
        IUser AddUser(String userName, String password, String email);
        IUser FindUser(String identifier);
    #endregion User

    #region Product
        IProduct AddProduct(...);
        void RemoveProduct(...);
    #endregion Product
}

Это очень простой до сих пор, и я могу делать такие вещи, как

IRepository MyRepository = new Repository(...);
MyRepository.AddUser(...);
MyRepository.RemoveProduct(...);

В идеале, я хочу что-то похожее на это

public interface IRepository
{
    #region User
        IUser User.User(String userName, String password, String email);
        IUser User.Find(String identifier);
    #endregion User

    #region Product
        IProduct Product.Add(...);
        void Product.Remove(...);
    #endregion Product
}

К сожалению, это не принято в C #. Я не могу добавить эти префиксы.

Я хочу использовать это вид пространства имен , чтобы написать что-то похожее на это

IRepository MyRepository = new Repository(...);
MyRepository.User.Add(...);
MyRepository.Product.Remove(...);

Я не хочу добавлять объекты User и Product в мой интерфейс, поскольку все, что мне нужно, - это способ улучшить чтение с помощью префиксов этого типа.

Есть идеи?

Спасибо

Ответы [ 7 ]

3 голосов
/ 10 марта 2011

Разделите его на два отдельных интерфейса.

public interface IRepositoryUser
{
    IUser Add(String userName, String password, String email);
    IUser Find(String identifier);
}

public interface IRepositoryProduct
{
    IProduct Add(...);
    void Remove(...);
}

public interface IRepository
{
    IRepositoryUser User { get; }
    IRepositoryProduct Product { get; }
}
1 голос
/ 10 марта 2011

Как насчет определения метода Add в IUser и метода Remove в IProduct, а затем в вашем IRepository просто определите IUser User {get; set;} и IProduct Product {get; set;}.

Полагаю, тогда ваш синтаксис MyRepository.User.Add(...); и MyRepository.Product.Remove(...); будет хорошо.

1 голос
/ 10 марта 2011

Ответьте, если вы говорите о шаблоне хранилища:

По моему скромному мнению и исходя из моего опыта, почему вы смешиваете продукты и пользователей?

Почему вы хотите использовать префикс методов репозитория?

Просто создайте репозиторий для любого типа объекта домена «IUserRepository» и «IProductRepository», и у вас не будет такого странного требования.

Я не знаю, есть ли у вас эта функция на другом языке программирования, но, даже если она у вас есть или нет, я нахожу плохой дизайн, делающий хранилище ответственным больше, чем тип объекта предмета.


Ответьте, если вы говорите о чем-либо еще

Тебе тоже нужно разделить проблемы.

Например, у вас будет служба данных, и вы хотите управлять пользователями и продуктами. Я бы посоветовал вам создать двух менеджеров: UsersManager и ProductsManager.

Оба будут связаны с DataServiceManager, так что вы можете иметь что-то вроде этого:

DataServiceManager dataServiceMan = new DataServiceManager();
dataServiceMan.Users.RegisterUser(...);
dataServiceMan.Products.CreateProduct(...);
1 голос
/ 10 марта 2011

То, что вы хотите, недопустимо в синтаксисе C #, как вы уже поняли.
Я предлагаю вам придерживаться вашей первой версии. Он понятен, доступен для чтения и соответствует стандартным правилам именования.

0 голосов
/ 10 марта 2011

Полагаю, вам нужна явная реализация интерфейса, как в примере ниже:

    ....................
    interface IOne
    {
       void MethodOne();
    }

    interface ITwo
    {
        void MethodTwo();
    }

    interface IThree
    {
        void MethodThree();
    }

    class TestIf : IOne, ITwo, IThree
    {
        void IThree.MethodThree()
        {
            MessageBox.Show("Method three");                
        }

        void IOne.MethodOne()
        {
            MessageBox.Show("Method one");
        }

        void ITwo.MethodTwo()
        {
            MessageBox.Show("Method two");
        }
    }
    ...................
    private void button1_Click(object sender, EventArgs e)
    {
        TestIf t = new TestIf();

        IOne one = t as IOne;
        ITwo two = t as ITwo;
        IThree three = t as IThree;

        one.MethodOne();
        two.MethodTwo();
        three.MethodThree();

    }

Обратите внимание, что при таком подходе вы можете вызывать методы интерфейса только путем явного преобразования объекта в указанный интерфейс

0 голосов
/ 10 марта 2011

Обычно это решается с использованием обобщений, поэтому вам нужно

  interface IRepository<T>

{
   T FindAll()
   T FindSingle(string id)

}

, а затем реализовать производные классы на основе интерфейса, почти всегда раздутые интерфейсы - это не путь и не ломается ISP

0 голосов
/ 10 марта 2011

Мне кажется, лучше отдельную логику для выполнения разных сущностей в разных классах репозитория а в базе IRepository хранятся только общие методы, такие как Add Remove Save Update и т. д. например

interface IRepository
{
   void Save();
   //other common methods
}
interface IProductRepository:IRepository
 {
   //Methods specified for products
 }
...