Quantcast
Channel: ASP.NET Core
Viewing all articles
Browse latest Browse all 9386

Understanding DI - Unity

$
0
0

I used the following to learn DI and its use inside the MVC application

http://www.c-sharpcorner.com/UploadFile/dacca2/implement-ioc-using-unity-in-mvc-5/

NuGet packages referenced in this article for unity, built the whole code for me and placed it inside the app_start folder. I created my interface and implemented it on a class, created the definition in the bootstrapper (UnityConfig class). 

#1:

Then i placed the following in my controller and i was able to get the information (static string) from my class method without any issue:

[Dependency]
public ISomeThing SomeThingInstance { get; set; }

#2:

Now, i took this one step further since a good project should be built in layers, every thing shouldn't be in the web application.

I created a new project "Core" in the solution and moved the DI code from app_start to here. 

Then created a "Repository" project with two folders "Services" and "Services Interfaces" and moved my ISomeThing interface and SomeThing class here.

Just like #1 example, i was able to use it without any issue in my controller. 

#3:

Then i took this one step further, and created a MVCBase Project. Put one HelperClass in there -- like in theory this project will house filters, extensions etc..

Now when i use the following in this HelperClass, i get an exception of type 'System.NullReferenceException' occurred in Unity.Test2.MvcBase.dll but was not handled in user code. Additional information: Object reference not set to an instance of an object.

namespace Unity.Test2.MvcBase.Helper
{
    public class DataHelper
    {


        [Dependency]
        public ISomeThing SomeThingInstance { get; set; }

                        
        public string GetSomthing()
        {
            return SomeThingInstance.ReturnedViaHelperclass(); //ERROR IS HERE
        }

    }
}

I was only able to create the object by doing following in the HelperClass - adding constructor method and then resolving the dependency manually.

namespace Unity.Test2.MvcBase.Helper
{
    public class DataHelper
    {


        //[Dependency]
        //public ISomeThing SomeThingInstance { get; set; }

        private ISomeThing SomeThingInstance {get; set;}

        public DataHelper()
        {
            var container = UnityConfig.GetConfiguredContainer();
            SomeThingInstance = container.Resolve<ISomeThing>();
        }
        public string GetSomthing()
        {
            return SomeThingInstance.ReturnedViaHelperclass();
        }

    }
}

Here is the controller code

namespace Unity.Test2.Controllers
{
    public class HomeController : Controller
    {
        [Dependency]
        public ISomeThing SomeThingInstance { get; set; }

        // GET: Home
        public ActionResult Index()
        {
            var model = new HomeIndexViewModel();
            model.Normal = SomeThingInstance.SomeThingGet();
            model.ViaDataHelper = new DataHelper().GetSomthing();
            return View(model);
        }
    }
}

Here is the unity config code created by the nuget package

namespace Unity.Test2.MvcBase.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
        public static void RegisterTypes(IUnityContainer container)
        {
            // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
            // container.LoadConfiguration();

            // TODO: Register your types here
            container.RegisterType<ISomeThing, SomeThing>();
        }
    }
}

and unity mvc activator class code created by nuget package

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Unity.Test2.MvcBase.App_Start.UnityWebActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Unity.Test2.MvcBase.App_Start.UnityWebActivator), "Shutdown")]

namespace Unity.Test2.MvcBase.App_Start
{
    /// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary>
    public static class UnityWebActivator
    {
        /// <summary>Integrates Unity when the application starts.</summary>
        public static void Start() 
        {
            var container = UnityConfig.GetConfiguredContainer();

            FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
            FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            // TODO: Uncomment if you want to use PerRequestLifetimeManager
            // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
        }

        /// <summary>Disposes the Unity container when the application is shut down.</summary>
        public static void Shutdown()
        {
            var container = UnityConfig.GetConfiguredContainer();
            container.Dispose();
        }
    }
}

Now, in case of #3, why do it need to resolve the dependency manually? Why can't i use it just like i have it in the controller? Am I missing something here?


Viewing all articles
Browse latest Browse all 9386

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>