ASP.NET MVC4 Unity - 解决对另一个项目的依赖关系

时间:2013-04-18 16:25:39

标签: asp.net-mvc dependency-injection unity-container

我在我的项目MVC4 Unity中有这个配置,并且在驱动程序中有一个通用的配置。

Bootstrapper.cs

namespace MyProyect.Web
{
    public static class Bootstrapper
    {
        public static void Initialise()
        {
            var container = BuildUnityContainer();
            ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
        }

        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            container.RegisterType<MyProyect.Model.DataAccessContract.ICountryDao, MyProyect.DataAccess.CountryDao>();
            container.RegisterType<MyProyect.Model.DataAccessContract.IContactDao, MyProyect.DataAccess.ContactDao>();

            return container;
        }
    }
}

的Global.asax:

    protected void Application_Start()
    {
        ...  
        Bootstrapper.Initialise();
        ...  
    }

GenericModelBinder.cs:

namespace MyProyect.Web.ModelBinder
{
    public class GenericModelBinder : DefaultModelBinder//, IValueProvider
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            var resolver = (Unity.Mvc4.UnityDependencyResolver)DependencyResolver.Current;
            if (modelType == null)
            {
                return base.CreateModel(controllerContext, bindingContext, null);
            }

            return resolver.GetService(modelType);
        }
    }
}

现在我需要解决解决方案中另一个项目的依赖关系。我的问题是如何识别Unity在另一个项目中的设置?我目前有这个类,但当前配置没有引入MVC项目。

namespace MyProyect.Model.ListData
{
    public abstract class ListDataGenericResolver
    {
        protected T ResolverType<T>()
        {
            IUnityContainer container = new UnityContainer();
            UnityServiceLocator locator = new UnityServiceLocator(container);
            ServiceLocator.SetLocatorProvider(() => locator);

            //return unity.Resolve<T>();
            return (T)container.Resolve(typeof(T));
        }
    }
}

这是一个如何使用ListDataGenericResolver

的示例
namespace MyProyect.Model.ListData.Types
{
    public class CountryListData : ListDataGenericResolver, IGetListData
    {
        private readonly ICountryDao countryDao;
        private string defaultValue;

        public CountryListData(object defaultValue)
        {
            // Resolver
            this.countryDao = this.ResolverType<ICountryDao>();
            this.defaultValue = defaultValue == null ? string.Empty : defaultValue.ToString();
        }

        public IList<SelectData> GetData()
        {
            var data = this.countryDao.GetAllCountry(new Entity.Parameters.CountryGetAllParameters());
            return data.Select(d => new SelectData
                {
                    Value = d.CountryId.ToString(),
                    Text = d.Description,
                    Selected = this.defaultValue == d.CountryId.ToString()
                }).ToList();
        }
    }
}

谢谢。

1 个答案:

答案 0 :(得分:1)

我是这样做的。

在Application_Start中,我创建了Unity容器。我有一个自定义库,我用于我通过NuGet导入的所有MVC项目,因此我调用其configure方法,然后调用其他项目的Configure()方法。您可以简单地省略自定义库并在此处添加该代码。所有这些都使我的Application_Start变得干净整洁。

protected void Application_Start()
{
    // Standard MVC setup
    // <removed>

    // Application configuration 
    var container = new UnityContainer();
    new CompanyName.Mvc.UnityBootstrap().Configure(container);
    new AppName.ProjectName1.UnityBootstrap().Configure(container);
    new AppName.ProjectName2.UnityBootstrap().Configure(container);

    // <removed>
}

这是自定义MVC库的UnityBootstrap类的代码

namespace CompanyName.Mvc
{
    /// <summary>
    /// Bootstraps <see cref="CompanyName.Mvc"/> into a Unity container.
    /// </summary>
    public class UnityBootstrap : IUnityBootstrap
    {
        /// <inheritdoc />
        public IUnityContainer Configure(IUnityContainer container)
        {
            // Convenience registration for authentication
            container.RegisterType<IPrincipal>(new InjectionFactory(c => HttpContext.Current.User));

            // Integrate MVC with Unity
            container.RegisterFilterProvider();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            return container;
        }
    }
}

然后,在其他项目中,我在那里有一个UnityBootstrap,它是从Application_Start调用的:

ProjectName1:

namespace AppName.ProjectName1
{
    public class UnityBootstrap : IUnityBootstrap
    {
        public IUnityContainer Configure(IUnityContainer container)
        {
            return container.RegisterType<IDocumentRoutingConfiguration, DocumentRoutingConfiguration>();
        }
    }
}

ProjectName2: - 你可以在这里看到,这个依赖于另一个库中的其他一些项目,它正在调用它们的Configure()方法来设置它们......

namespace AppName.ProjectName2
{
    public class UnityBootstrap : IUnityBootstrap
    {
        public IUnityContainer Configure(IUnityContainer container)
        {
            new CompanyName.Security.UnityBootstrap().Configure(container);
            new CompanyName.Data.UnityBootstrap().Configure(container);

            container.RegisterSecureServices<AuthorizationRulesEngine>(typeof(UnityBootstrap).Assembly);

            return container
                .RegisterType<IAuthorizationRulesEngine, AuthorizationRulesEngine>()
                .RegisterType<IDateTimeFactory, DateTimeFactory>()
                .RegisterType<IDirectoryInfoFactory, DirectoryInfoFactory>()
                .RegisterType<IDirectoryWrapper, DirectoryWrapper>()
                .RegisterType<IEmailService, EmailService>()
                .RegisterType<IEntryPointService, EntryPointService>();
        }
    }
}

以下是整个上述代码中使用的IUnityBootstrap接口(供您参考)

/// <summary>
/// Defines a standard interface for bootstrapping an assembly into a Unity container.
/// </summary>
public interface IUnityBootstrap
{
    /// <summary>
    /// Registers all of the assembly's classes to their public interfaces and performs any other necessary configuration.
    /// </summary>
    /// <param name="container">The Unity container instance to configure.</param>
    /// <returns>The same IUnityContainer object that this method was called on.</returns>
    IUnityContainer Configure(IUnityContainer container);
}

我希望这可以帮助你。