簡體   English   中英

基於Marker接口將Unity容器中的接口注冊為不同的生存時間

[英]Register Interface in Unity Container based on Marker interface into different Lifetime

我的解決方案中有多個項目:

Core
Repository
Service
WebAPi

我的Unity注冊在WebAPi項目上。

我想要實現的是我過去在溫莎城堡所做的事情,現在我想通過Unity做到這一點:使用約定https://github.com/castleproject/Windsor/blob/master/docs/registering注冊界面-components-by-conventions.md

我有兩個Marker接口。

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/

如上例中給出的那樣,有一種方法可以根據標記接口來完成在溫莎城堡的工作?

鑒於:

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否則一切都是短暫的,但是您可以使規則更加明確(例如,如果找不到有效的標記接口,則拋出該ISingletonDependency )。

如果您可以縮小AllClasses.FromAssembliesInBasePath().Where where子句, 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM