Using MEF from both DSL and T4
-
28 Nisan 2010 Çarşamba 14:51
Not sure if this is a question for the MEF guys, the text templating guys or the DSL tools guys :-(...
I'm using the DSL tools to build a DSL, and T4 for the code generator. In my custom DSL code I satisfy the imports for one of my parts using the call
Microsoft.VisualStudio.Modeling.Shell.ModelingCompositionContainer.CompositionService.SatisfyImportsOnce(this);
This works fine when the code is executed within the DSL/Visual Studio environment. I'm a MEF novice, but I assume that the assembly containing the [Export] will end up being registered with the VisualStudio global composition service, and then the SatisfyImportsOnce call will then allow the [Import] within the class to be resolved against this export.
However, when the same code is called from the code generator the call fails as ModelingCompositionContainer.CompositionService
Thanks,
Kevin
now returns null. So if the VisualStudio global composition service isn't available in this context then in what container is the [Export] being registered when called in this context? And how could I write something equivalent to the SatisfyImportsOnce call that would work when called from both the DSL/Visual Studio environment and the text templating context?
Tüm Yanıtlar
-
05 Ağustos 2011 Cuma 15:23
Not that what I've done is identical to yours, but I'm using T4 to generate imports and a mock data layer (using simple lists, for testing) with [Export] and have no problems.
Imports:
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ output extension=".cs" #> <# // Variables var entities = new ttEntity[] { new ttEntity() { ClassName = "Products", EntityName = "Product" } }; #> using System; using System.Collections.Generic; using System.Linq; using System.Diagnostics.Contracts; using System.ComponentModel.Composition; using Contoso.Business.Entities; using Contoso.Helper; // <autogenerated> // This code was generated by a T4 template. Any changes made manually will be lost the next time this code is regenerated. // </autogenerated> namespace Contoso.Business { <# foreach (var entity in entities) { #> public static partial class <#= entity.ClassName #> { #region Property [IEnum<i<#= entity.ClassName #>> _Providers] [ImportMany(typeof(Contoso.Business.Interfaces.i<#= entity.ClassName #>))] private static IEnumerable<Contoso.Business.Interfaces.i<#= entity.ClassName #>> _Providers; #endregion
Mock DAL Exports:
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ output extension=".cs" #> <# // Variables var entities = new ttEntity[] { new ttEntity() { ClassName = "Products", EntityName = "Product" } }; #> using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using System.Text; using Contoso.Business.Entities; // <autogenerated> // This code was generated by a T4 template. Any changes made manually will be lost the next time this code is regenerated. // </autogenerated> namespace Contoso.Data.Mock { <# foreach (var entity in entities) { #> [Export(typeof(Contoso.Business.Interfaces.i<#= entity.ClassName #>))] public class <#= entity.ClassName #> : Contoso.Business.Interfaces.i<#= entity.ClassName #> { private readonly List<<#= entity.EntityName #>> _list = new List<<#= entity.EntityName #>>(); public IEnumerable<<#= entity.EntityName #>> Get() { return _list.ToList(); } public <#= entity.EntityName #> Get(Int32 Id) { return _list.SingleOrDefault(x => x.Id == Id); }
only reason I use ttEntity with ClassName and EntityName is because pluralization isn't always just an 's' suffix (ies)