фабрика, generic
От: mitrofanofff  
Дата: 02.07.10 08:25
Оценка:
доброго времени суток!
есть некая иерархия :
    public interface IDBEntity
    {
    //any code
    }

    public class Country : IDBEntity
    {
    //any code
    }

    public interface IDBEntityValidator<T> where T : IDBEntity
    {
    //any code
    }
    public class CountryValidator : IDBEntityValidator<Country>
    {
    //any code
    }


хочется создать фабрику, создающую конкретный валидатор по типу сущности. примерно так:
    public class DBEntityValidatorFactory
    {

        public static IDBEntityValidator<T> getValidator<T>(T entity) where T : IDBEntity
        {
            return ????
        }
    }


что здесь должно быть?

использовать хочется примерно так:
    public abstract class Repository<T> where T : IDBEntity
    {
    //any code...

        public virtual void SaveOrUpdateEntity<K>(K entity) where K : T
        {
            session = Domain.CurrentSession;
            ITransaction transaction = session.BeginTransaction();
            try
            {
                IDBEntityValidator<K> validator = DBEntityValidatorFactory.getValidator(entity);
                if(validator != null)
                {
            // необходимые проверки в валидаторе...

                    session.SaveOrUpdate(entity);
                    session.Flush();
                    transaction.Commit();
                }
                else
                {
                    transaction.Rollback();
                    throw new Exception("Не удалось найти валидатор!");
                }
            }
            catch (TransactionException exception)
            {
                transaction.Rollback();
                throw new Exception(exception.Message);
            }
            finally
            {
                LockEntity(entity, true);
            }
        }


заранее благодарен за любые ответы
Re: фабрика, generic
От: LF  
Дата: 02.07.10 08:36
Оценка: :)
Я для подобных целей использую dependency injection, в частности Unity
Re[2]: фабрика, generic
От: mitrofanofff  
Дата: 02.07.10 08:56
Оценка:
Здравствуйте, LF, Вы писали:

LF>Я для подобных целей использую dependency injection, в частности Unity


нельзя ли по-подробней? немного погуглив пришёл к выводу, что суть сводится примерно к следующему:


        public static IDBEntityValidator<T> getValidator<T>(T entity) where T : IDBEntity
        {
            return new CountryValidator(); //в зависимости от типа сущности (пока не важно - свитчем делать или нет)
        }

однако здесь будет ошибка приведения типов.
или я не прав?
Re[3]: фабрика, generic
От: LF  
Дата: 02.07.10 09:02
Оценка:
M>нельзя ли по-подробней?
Суть в том, что у нас есть некий контейнер,
который по типу интерфейса вернет конкретный экземпляр.
В вашем случае фабрика вообще не нужна, а можно сделать так:
на этапе инициализации регистрируем типы:
container.RegisterInstance<IDBEntityValidator<Country>>(new CountryValidator());
...

потом в программе:
var validator = container.Resolve<IDBEntityValidator<Country>>();

По сути, DI контейнер является фабрикой, только не узкоспециализированной, а общего назначения.

ЗЫ. Регистрацию необязательно производить явно, есть куча контейнеров, которые делают это автоматически на основе заданных правил.
Re: фабрика, generic
От: _FRED_ Черногория
Дата: 02.07.10 09:19
Оценка:
Здравствуйте, mitrofanofff, Вы писали:

M>хочется создать фабрику, создающую конкретный валидатор по типу сущности. примерно так:

M>    public class DBEntityValidatorFactory
M>    {

M>        public static IDBEntityValidator<T> getValidator<T>(T entity) where T : IDBEntity
M>        {
M>            return ????
M>        }
M>    }

M>что здесь должно быть?

Например, обращение к словарю, клчём в котором был бы тип T, а значением — метод, создающий валидатор, соответствующий ключу.
Другой вариант — добавить в IDBEntity метод "getValidator".
Help will always be given at Hogwarts to those who ask for it.
Re[2]: фабрика, generic
От: mitrofanofff  
Дата: 02.07.10 09:26
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, mitrofanofff, Вы писали:


M>>хочется создать фабрику, создающую конкретный валидатор по типу сущности. примерно так:

_FR>
M>>    public class DBEntityValidatorFactory
M>>    {

M>>        public static IDBEntityValidator<T> getValidator<T>(T entity) where T : IDBEntity
M>>        {
M>>            return ????
M>>        }
M>>    }
_FR>

M>>что здесь должно быть?

_FR>Например, обращение к словарю, клчём в котором был бы тип T, а значением — метод, создающий валидатор, соответствующий ключу.

_FR>Другой вариант — добавить в IDBEntity метод "getValidator".

но тут, скорее, стоит вопрос о приведении типов. (IDBEntityValidator<T>)CountryValidator не работает...=(
Re[3]: фабрика, generic
От: _FRED_ Черногория
Дата: 02.07.10 09:28
Оценка: 2 (1)
Здравствуйте, mitrofanofff, Вы писали:

M>но тут, скорее, стоит вопрос о приведении типов. (IDBEntityValidator<T>)CountryValidator не работает...=(


Если положить, что T — это Country, то нужно так:

return (IDBEntityValidator<T>)(object)(new CountryValidator());
Help will always be given at Hogwarts to those who ask for it.
Re[4]: фабрика, generic
От: mitrofanofff  
Дата: 02.07.10 09:42
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, mitrofanofff, Вы писали:


M>>но тут, скорее, стоит вопрос о приведении типов. (IDBEntityValidator<T>)CountryValidator не работает...=(


_FR>Если положить, что T — это Country, то нужно так:


_FR>
_FR>return (IDBEntityValidator<T>)(object)(new CountryValidator());
_FR>


спасибо, так работает. дальше буду думать как сделать покрасивше =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.