Microsoft Unity 2,如何注册以下内容?

时间:2011-05-19 16:01:40

标签: c# .net dependency-injection unity-container ioc-container

现在我们有一个包含所有数据库调用的dll文件,我无法更改它。但是我需要从我的Mvc 3项目中打电话给我。调用它的过程很简单,我使用以下内容:

ManageProvider.GetProxy<T>(ident);

T是我希望从中获取类的接口(它类似于它自己的IoC),ident是用户标识类。所以通过调用

var classReturned = ManageProvider.GetProxy<ICommunity>(new UserIden{ Email = "test@test.com" });

我会让所有社区功能退回课程。 现在我想在我的Mvc 3项目中实现Unity。问题是,我能以某种方式通过统一将这些调用添加到dll文件中吗?

我希望使用以下方法解决此问题:

var classReturned = myContainer.Resolve<ICommunity>(new UserIden{ Email = "test@test.com" });

我如何在Unity中注册(或者甚至可以)?

更新

1)使用email / user ident调用方法而不是定义Dependency属性更好吗? (以下)

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文件的所有项目的所有逻辑。

关于ManagerProvider。它接受一个接口并返回映射到该接口的类。所以对于社区来说,界面看起来像这样(删除了很​​多调用以保持简短,还有帖子,评论,社区创建/更新等):

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)...返回类。

,该类对所有其他接口也是如此
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()));

2 个答案:

答案 0 :(得分:3)

我认为你需要隐藏另一个抽象背后的创作,例如:

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);
    }
}

这将隐藏此抽象背后的ManageProviderUserIden,并允许您稍后将其替换为更有用的内容并使测试更容易。

现在注册非常简单:

RegisterType<ICommunityRepository, ManageProviderCommunityRepository>();

不要调用myContainer.Resolve(就像在示例中那样),而是在类中注入依赖项。这会阻止您使用Service Locator anti-pattern

答案 1 :(得分:0)

也许你可以使用InjectionFactory做这样的事情:

    myContainer.RegisterType<ICommunity>(
        new InjectionFactory(c => ManageProvider.GetProxy<ICommunity>(new UserIden {Email = "test@test.com"})));
    var classReturned = myContainer.Resolve<ICommunity>();

...虽然您无法将UserIden作为参数传递给Resolve调用,但我不确定这是否是您想要的。

要注册程序集的所有公共类,您可以迭代Assembly.GetTypes()并以相同的方式注册它们?