开发者

Microsoft Unity 2, how to register the following?

Right now we have a dll file that contains all the database calls and i can't change it. However i need to call i from my Mvc 3 project. The process to call it is simple, i use the following:

ManageProvider.GetProxy<T>(ident);

T is an interface that i want to get the class back from (its like an IoC of its own) and ident is the user identification class. So by calling

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

I would get a class back with all the community functions. Now i want to implement Unity in my Mvc 3 project. The question is, can i somehow add these calls to the dll file through unity?

I want to resolve the call by using:

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

How can i register this in Unity (or is it even possible) ?

Update:

1) Is it better to call the methods with the email/user ident instead of defining a Dependency property? (ex below)

2) There is a bout 20 or so interfaces in the dll file right now. Should i add them all to the same reposatory? (ex below)

    public class ProxyWrapper : IDllRepository
    {
        [Dependency]
        public UserIdent UserIde开发者_运维百科nt { 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();
    }

Whats the best way and how would i call it from my code? Does the [Dependency] attribute also fall into the Service Locator anti pattern?

Update 23.05.11

1) Yes, something like that. They contain all the logic that is provided to all the projects that includes the dll file.

Regarding the ManagerProvider. It accepts an interface and returns the class that is mapped to this interface. So for the community, the interface looks like this (removed a lot of calls to keep it short, there is also posts, comments, community create/update etc):

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) What i can't update is how the ManageProvider.GetProxy works. The GetProxy is a class in the dll file that is hardcoded. Here is the part for the community. The class does the same for all the other interfaces as well, if typeof(interface) ... return class.

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

3) Once registered using this new wrapper class, i can call it through the following code (MvcUnityContainer is a static class that only has a property called 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));

The question is, do i need the static class MvcUnityContainer? Is it possible to configure the DependecyResolver to do that for me? Something like (problem is that it doesn't accept the override parameter):

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


I think you need to hide the creation behind another abstraction, for instance:

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

This will hide both the ManageProvider and the UserIden behind this abstraction, and allows you to replace it later on with something more useful and makes testing easier.

Registration now is very easy:

RegisterType<ICommunityRepository, ManageProviderCommunityRepository>();

Instead of calling myContainer.Resolve (as you do in your example), inject the dependencies in your classes. This prevents you from using the Service Locator anti-pattern.


Perhaps you could do something like this, using the InjectionFactory:

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

... Though you wouldn't be able to pass the UserIden as a parameter to the Resolve call, so I'm not sure if this is what you want.

To register all the public classes of the assembly you could perhaps iterate over Assembly.GetTypes() and register them in the same way?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜