2017-07-13 17 views
1

我在我的解决方案多个项目:注册界面在Unity基于容器的标记接口,为不同的生命周期上

Core 
Repository 
Service 
WebAPi 

我的统一登记上的WebAPI项目。

我想实现的东西我已经在温莎城堡在过去所做的,现在我想这样做,通过Unity:使用约定https://github.com/castleproject/Windsor/blob/master/docs/registering-components-by-conventions.md

我有两个标记接口寄存器接口。

public interface ISingletonDependency{} 
public interface ITransientDependency{} 

对于我的仓库或服务类我做的:

public interface IPersonRepository:ISingletonDependency{ 
... 
... 

} 

public class PersonRepository: IPersonRepository{ 
... 
... 
... 
} 

在我的服务类:

public interface IPersonService:ISingletonDependency{ 
... 
...  
} 

public class PersonService: IPersonService{ 
... 
... 
... 
} 

我在DI和类似的方式做到这一点对所有我的班在注册期间,我曾经这样做:

container.Register(
    Classes.NamedAssembly("SolutionName.Repository") 
     .BasedOn<ISingletonDependency>() 
     .WithService.FromInterface().LifestyleSingleton() 
); 


container.Register(
    Classes.NamedAssembly("SolutionName.Service") 
     .BasedOn<ISingletonDependency>() 
     .WithService.FromInterface().LifestyleSingleton() 
); 


container.Register(
    Classes.NamedAssembly("SolutionName.Repository") 
     .BasedOn<ITransientDependency>() 
     .WithService.FromInterface().LifestyleTansient() 
); 


container.Register(
    Classes.NamedAssembly("SolutionName.Service") 
     .BasedOn<ITransientDependency>() 
     .WithService.FromInterface().LifestyleTansient() 
); 

这种方式我不需要为每个人都做到这一点,我看到了Unity的方法,但它的确基于命名约定 ,您无法单独指定单身或瞬间生活方式。

https://blogs.msdn.microsoft.com/agile/2013/03/12/unity-configuration-registration-by-convention/

有没有办法做到,你可以在温莎城堡做什么,在我给,基于标记的接口上面的例子?

+1

'我已经在温莎城堡进行的过去,现在我想通过Unity这样做.. 。 - 为什么你要从一个完全支持的DI容器移动到一个死的*容器? Unity [不再支持](https://github.com/unitycontainer/unity/issues),甚至当它在功能上严重落后时。微软[放弃了对它的支持](https://blogs.msdn.microsoft.com/dotnet/2015/08/21/the-future-of-unity/),但新的所有者不在意支持它要么 - 一年半没有承诺。 – NightOwl888

+0

+100对于@ NightOwl888的评论:) – Steven

回答

0

考虑:

public interface ISingletonDependency { } 
public interface ITransientDependency { } 

public interface IPersonRepository : ISingletonDependency { } 
public class PersonRepository : IPersonRepository { } 

public interface IPersonService : ITransientDependency { } 
public class PersonService : IPersonService { } 

然后,你可以使用注册类型:

var container = new UnityContainer(); 

container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath().Where(
     // Could also match on namespace etc. here 
     t => t.Assembly.GetName().Name.StartsWith("SolutionName")), 
    WithMappings.FromMatchingInterface, 
    WithName.Default, 
    WithLifetime.FromMarkerInterface); 

// Singleton 
Debug.Assert(ReferenceEquals(container.Resolve<IPersonRepository>(), container.Resolve<IPersonRepository>())); 

// Transient 
Debug.Assert(!ReferenceEquals(container.Resolve<IPersonService>(), container.Resolve<IPersonService>())); 

WithLifetime.FromMarkerInterface是使用标记接口来选择正确的LifetimeManager定制的约定:

public static class WithLifetime 
{ 
    public static LifetimeManager FromMarkerInterface(Type type) 
    { 
     if (typeof(ISingletonDependency).IsAssignableFrom(type)) 
     { 
      return new ContainerControlledLifetimeManager(); 
     } 

     return new TransientLifetimeManager(); 
    } 
} 

在这种情况下,一切都是暂时的,除非它是一个ISingletonDependency但您可以使规则更明确(例如,如果没有找到有效的标记界面,则抛出)。

如果你可以缩小你在哪里子句AllClasses.FromAssembliesInBasePath().Where那么你很可能逃脱一个内衬:

container.RegisterTypes(
AllClasses.FromAssembliesInBasePath().Where(
    t => t.Namespace.StartsWith("SolutionName.Repository") || 
     t.Namespace.StartsWith("SolutionName.Service")), 
    WithMappings.FromMatchingInterface, 
    WithName.Default, 
    WithLifetime.FromMarkerInterface); 
相关问题