asp.net mvc एएसपी.नेट एमवीसी 4 और एएसपी.नेट वेब एपीआई के साथ एमईएफ को एकीकृत कैसे करें




asp.net-mvc asp.net-mvc-4 (5)

श्री केनी टॉर्डुअर्स का समाधान मेरे लिए काम करता था, जबकि सही सही उत्तर नहीं था (नियंत्रक उदाहरण को हल नहीं कर सका हालांकि सभी आश्रित भागों catelog में हैं, मुझे "प्रकार का डिफॉल्ट कन्स्ट्रक्टर नहीं है" त्रुटि दी गई थी)!

सुधार : दोनों दृष्टिकोण वास्तव में काम करते हैं, मैं सम्मेलन भागों रजिस्ट्री में एक प्राथमिक गलती से बेवकूफ था। सही उत्तर के लेखक को मेरी ईमानदारी से माफी।

एक ही प्रोजेक्ट में एएसपी.नेट एमवीसी 4 और एएसपी.नेट वेब एपीआई के साथ प्रबंधित एक्सटेंसिबिलिटी फ्रेमवर्क (एमईएफ) कैसे एकीकृत करता है?

एक एमवीसी नियंत्रक HomeController और एक वेब एपीआई नियंत्रक ContactController साथ एक उदाहरण अनुप्रयोग पर विचार करें। दोनों में IContactRepository की एक संपत्ति है, जिसे वे हल करने के लिए एमईएफ पर भरोसा करते हैं। समस्या यह है कि एमईएफ और वेब एपीआई में एमईएफ को कैसे प्लग करें, ताकि उदाहरण एमईएफ के माध्यम से बनाए जा सकें।

HomeController:

/// <summary>
/// Home controller. Instruct MEF to create one instance of this class per importer,
/// since this is what MVC expects.
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller
{
    [Import]
    private IContactRepository _contactRepository = null;

    public ActionResult Index()
    {
        return View(_contactRepository.GetAllContacts());
    }
}

ContactController:

/// <summary>
/// Contact API controller. Instruct MEF to create one instance of this class per importer,
/// since this is what Web API expects.
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ContactController : ApiController
{
    [Import]
    private IContactRepository _contactRepo = null;

    public Contact[] Get()
    {
        return _contactRepo.GetAllContacts();
    }
}

आईसीओन्टैक्ट रिपोजिटरी और संपर्क रिपोजिटरी:

public interface IContactRepository
{
    Contact[] GetAllContacts();
}

[Export(typeof(IContactRepository))]
public class ContactRepository : IContactRepository
{
    public Contact[] GetAllContacts()
    {
        return new Contact[] {
            new Contact { Id = 1, Name = "Glenn Beck"},
            new Contact { Id = 2, Name = "Bill O'Riley"}
        };
    }
}

संपर्क करें:

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
}

समाधान System.Web.Mvc.IDependencyResolver और System.Web.Http.Dependencies.IDependencyResolver लागू करना है और आपके Application_Start विधि में क्रमशः एएसपी.नेट एमवीसी और एएसपी.नेट वेब एपीआई के साथ अपना कार्यान्वयन पंजीकृत करना है।

इस उदाहरण में हम एक क्लास MefConfig , जो हमारे निर्भरता रिज़ॉल्वर को स्थापित करने के लिए Application_Start से कॉल की जाने वाली एक विधि RegisterMef लागू करता है। क्लास MefDependencyResolver System.Web.Mvc.IDependencyResolver और System.Web.Http.Dependencies.IDependencyResolver दोनों को लागू करता है और, जैसे, एमवीसी और वेब एपीआई दोनों के लिए निर्भरता रिज़ॉल्यूशन कर्तव्यों को संभालता है।

Application_Start, इसे अपने Global.asax.cs में रखें:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        [...]
        MefConfig.RegisterMef();
    }
}

MefDependencyResolver और MefConfig:

/// <summary>
/// Resolve dependencies for MVC / Web API using MEF.
/// </summary>
public class MefDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
    private readonly CompositionContainer _container;

    public MefDependencyResolver(CompositionContainer container)
    {
        _container = container;
    }

    public IDependencyScope BeginScope()
    {
        return this;
    }

    /// <summary>
    /// Called to request a service implementation.
    /// 
    /// Here we call upon MEF to instantiate implementations of dependencies.
    /// </summary>
    /// <param name="serviceType">Type of service requested.</param>
    /// <returns>Service implementation or null.</returns>
    public object GetService(Type serviceType)
    {
        if (serviceType == null)
            throw new ArgumentNullException("serviceType");

        var name = AttributedModelServices.GetContractName(serviceType);
        var export = _container.GetExportedValueOrDefault<object>(name);
        return export;
    }

    /// <summary>
    /// Called to request service implementations.
    /// 
    /// Here we call upon MEF to instantiate implementations of dependencies.
    /// </summary>
    /// <param name="serviceType">Type of service requested.</param>
    /// <returns>Service implementations.</returns>
    public IEnumerable<object> GetServices(Type serviceType)
    {
        if (serviceType == null)
            throw new ArgumentNullException("serviceType");

        var exports = _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
        return exports;
    }

    public void Dispose()
    {
    }
}

public static class MefConfig
{
    public static void RegisterMef()
    {
        var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var container = new CompositionContainer(asmCatalog);
        var resolver = new MefDependencyResolver(container);
        // Install MEF dependency resolver for MVC
        DependencyResolver.SetResolver(resolver);
        // Install MEF dependency resolver for Web API
        System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }
}

मैंने @ अक्कुद्दी 1 के जवाब का पालन किया लेकिन मुझे इसे नियंत्रक फैक्टरी को भी बदलना पड़ा:

public class MefControllerFactory : DefaultControllerFactory
{
    private readonly CompositionContainer compositionContainer;

    public MefControllerFactory(CompositionContainer compositionContainer)
    {
        this.compositionContainer = compositionContainer;
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        var export = compositionContainer.GetExports(controllerType, null, null).SingleOrDefault();

        IController result;

        if (null != export)
        {
            result = export.Value as IController;
        }
        else
        {
            result = base.GetControllerInstance(requestContext, controllerType);
            compositionContainer.ComposeParts(result);
        }

        return result;
    }
}

Glogal.asax.cs

protected void Application_Start()
{
    ...
    var container = MefConfig.Register();
    ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));
}

आप इस http://kennytordeur.blogspot.be/2012/08/mef-in-aspnet-mvc-4-and-webapi.html पर एक नज़र डाल सकते हैं। यह बताता है कि एएसपीनेट एमवीसी 4 / वेब एपीआई प्रोजेक्ट में एमईएफ का उपयोग कैसे करें। इस कोड के आधार पर एक Nuget पैकेज भी मौजूद है। इस तरह आप इसे बहुत आसानी से और जल्दी से परीक्षण कर सकते हैं।


@ aknuds1 उत्तर सबसे अच्छा है जिसे मैंने एमईएफ को निर्भरता रिसेल्वर में एकीकृत करने के लिए अब तक देखा है। मैं इसे एमईएफ 2 में काफी आसानी से सम्मेलन-आधारित संरचना का उपयोग करने के लिए विस्तारित करने में सक्षम था। MefConfig क्लास वह सब कुछ है जिसे बदलने की जरूरत है और फिर बहुत कुछ नहीं।

/// <summary>
///     Responsible for configuring MEF for the application.
/// </summary>
public static class MefConfig
{
    /// <summary>
    ///     Registers MEF conventions and exports.
    /// </summary>
    public static void RegisterMef()
    {
        // Register MVC/API conventions
        var registrationBuilder = new RegistrationBuilder();
        registrationBuilder.ForTypesDerivedFrom<Controller>().SetCreationPolicy(CreationPolicy.NonShared).Export();
        registrationBuilder.ForTypesDerivedFrom<ApiController>().SetCreationPolicy(CreationPolicy.NonShared).Export();
        var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly(), registrationBuilder);
        var aggregateCatalog = new AggregateCatalog(assemblyCatalog);
        var container = new CompositionContainer(aggregateCatalog);
        var resolver = new MefDependencyResolver(container);
        // Install MEF dependency resolver for MVC
        DependencyResolver.SetResolver(resolver);
        // Install MEF dependency resolver for Web API
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }
}




mef