Microsoft Unity 2, как зарегистрировать следующее?

Прямо сейчас у нас есть файл dll, который содержит все вызовы базы данных, и я не могу его изменить. Однако мне нужно позвонить мне из моего проекта Mvc 3. Процесс его вызова прост, я использую следующее:

ManageProvider.GetProxy<T>(ident);

T - это интерфейс, из которого я хочу вернуть класс (это как собственный IoC), а ident - это класс идентификации пользователя. Итак, позвонив

var classReturned = ManageProvider.GetProxy<ICommunity>(new UserIden{ Email = "[email protected]" });

Я бы вернул класс со всеми функциями сообщества. Теперь я хочу реализовать Unity в своем проекте Mvc 3. Вопрос, можно ли как-то через юнити добавить эти вызовы в dll файл?

Я хочу разрешить вызов, используя:

var classReturned = myContainer.Resolve<ICommunity>(new UserIden{ Email = "[email protected]" });

Как я могу зарегистрировать это в Unity (или это вообще возможно)?

Обновление:

1) Лучше ли вызывать методы с идентификатором электронной почты/пользователя вместо определения свойства зависимости? (пример ниже)

2) Прямо сейчас в файле dll есть около 20 интерфейсов. Должен ли я добавить их все в один и тот же репозиторий? (пример ниже)

    public class ProxyWrapper : IDllRepository
    {
        [Dependency]
        public UserIdent UserIdent { get; set; }

        public ICommunity GetCommunity()
        {
            return ManageProvider.GetProxy<ICommunity>(UserIdent);
        }

        public IDesktop GetDesktop()
        {
            return ManageProvider.GetProxy<IDesktop>(UserIdent);
        }
    }

    public interface IDllRepository
    {
        ICommunity GetCommunity();
        IDesktop GetDesktop();
    }

Каков наилучший способ и как бы я назвал это из моего кода? Подпадает ли атрибут [Dependency] под антишаблон Service Locator?

Обновление 23.05.11

1) Да, как-то так. Они содержат всю логику, предоставляемую всем проектам, включающим файл dll.

Что касается менеджера провайдера. Он принимает интерфейс и возвращает класс, сопоставленный с этим интерфейсом. Итак, для сообщества интерфейс выглядит так (удалено много вызовов, чтобы сделать его кратким, также есть сообщения, комментарии, создание/обновление сообщества и т. д.):

List<CommunityThread> GetThreads(int pStartRowIndex, int pMaximumRows, string pOrderBy, string pSearchExpression);
Guid? CreateThread(string pTitle, string pDescription, string pPostContent);
bool DeleteThread(Guid pThreadId);
List<CommunityThread> GetCommunityUserThreads(Guid pCommunityUserId); 

2) Что я не могу обновить, так это то, как работает ManageProvider.GetProxy. GetProxy — это жестко закодированный класс в файле dll. Вот часть для сообщества. Класс делает то же самое и для всех остальных интерфейсов, если typeof(interface) ... return class.

private static IManageProxy GetProxyForInterface<T>(UserIdent pIdent)
{
....
     if (typeof(T).Equals(typeof(ICommunity)))
          return new PCommunity();
....
}

3) После регистрации с использованием этого нового класса-оболочки я могу вызвать его с помощью следующего кода (MvcUnityContainer — это статический класс, который имеет только свойство, называемое Container):

var c = MvcUnityContainer.Container.Resolve<IBackendRepository>(new PropertyOverride("UserIdent",
                                                                           new UserIdent()));

Global.asax

IUnityContainer container = InitContainer();                                 
MvcUnityContainer.Container = container;
DependencyResolver.SetResolver(new UnityMvcResolver(container));

Вопрос в том, нужен ли мне статический класс MvcUnityContainer? Можно ли настроить DependecyResolver для этого? Что-то вроде (проблема в том, что он не принимает параметр переопределения):

var c = DependencyResolver.Current.GetService<IBackendRepository>(new PropertyOverride("UserIdent", new UserIdent()));

person Patrick    schedule 19.05.2011    source источник
comment
Патрик, я не уверен, что понимаю твой замысел. 1. Какой тип интерфейса на самом деле возвращает GetProxy‹T›? 2. Эти 20 интерфейсов, это ICommunity, IDesktop и т. д. Это объекты вашего домена? Можете ли вы описать, какова структура той части системы, которую вы не можете изменить? Покажите это кодом, а не словами.   -  person Steven    schedule 21.05.2011
comment
Обновлен вопрос, чтобы ответить на вопросы.   -  person Patrick    schedule 23.05.2011


Ответы (2)


Я думаю, вам нужно скрыть создание за другой абстракцией, например:

public interface ICommunityRepository
{
    ICommunity GetByEmailAddress(string address);
}

public class ManageProviderCommunityRepository
    : ICommunityRepository
{
    public ICommunity GetByEmailAddress(string address)
    {
        var id = new UserIden { Email = address };
        return ManageProvider.GetProxy<ICommunity>(id);
    }
}

Это скроет как ManageProvider, так и UserIden за этой абстракцией, и позволит вам позже заменить ее чем-то более полезным и упростит тестирование.

Зарегистрироваться сейчас очень просто:

RegisterType<ICommunityRepository, ManageProviderCommunityRepository>();

Вместо вызова myContainer.Resolve (как в вашем примере) введите зависимости в свои классы. Это не позволит вам использовать анти-шаблон Service Locator.

person Steven    schedule 19.05.2011
comment
Разве я не могу просто создать новый класс с интерфейсом ICommunity вместо создания нового интерфейса? - person Patrick; 20.05.2011
comment
Я не знаю, потому что я не знаю, что вы пытаетесь сделать. Обновите свой вопрос этой информацией, и, возможно, я смогу сказать что-то полезное :-) - person Steven; 20.05.2011

Возможно, вы могли бы сделать что-то подобное, используя InjectionFactory:

    myContainer.RegisterType<ICommunity>(
        new InjectionFactory(c => ManageProvider.GetProxy<ICommunity>(new UserIden {Email = "[email protected]"})));
    var classReturned = myContainer.Resolve<ICommunity>();

... Хотя вы не сможете передать UserIden в качестве параметра для вызова Resolve, поэтому я не уверен, что вы этого хотите.

Чтобы зарегистрировать все общедоступные классы сборки, вы, возможно, могли бы перебрать Assembly.GetTypes() и зарегистрировать их таким же образом?

person JagdPanther    schedule 19.05.2011
comment
Мне нужно иметь возможность передать UserIdent в единство/получить прокси. Он возьмет электронную почту вошедшего в систему пользователя, а затем вызовет GetProxy. - person Patrick; 20.05.2011