现在我们有一个包含所有数据库调用的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()));
答案 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);
}
}
这将隐藏此抽象背后的ManageProvider
和UserIden
,并允许您稍后将其替换为更有用的内容并使测试更容易。
现在注册非常简单:
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()并以相同的方式注册它们?