2
votes

I've got a Visual Studio extension, where much of the functionality is written through MEF. So far, my individual functionality is per ITextBuffer, so I have used the Properties member to cache instances.

However, now I have some functionality that needs to be per-project and per-solution. The EnvDTE classes offer a Properties object but I couldn't figure out whether or not they could store my own arbitrary data. I really don't want to make my own data static.

How can I store per-project and per-solution data without having to resort to global variables?

Edit:

I might also mention that since you can't use MEF imports for static data, even if you hide it in something like a Singleton, then using the global variable route is physically impossible. So I really, really need something that is not a global.

Edit:

I'm talking about object references, not persistent values. I don't need to store anything in a solution or project file, only with the object.

2
Can you give some examples/screenshots? I am not very familiar with MEF, and this is probably why your questions looks unclear to me.Neolisk
@Neolisk: What do you want a screenshot of, the documentation of MEF saying that you can't import static members? Or the documentation of EnvDTE.Solution/EnvDTE.Project that don't have user-available storage space?Puppy
No offence, I'm just trying to increase chances of this question being answered, if not me, somebody else will. The more information you provide, the better. You don't want to burn your bounty for nothing, right? Yes, links to relevant parts of documentation would help.Neolisk
Are you looking for IVsSolutionPersistence for per-solution? for per-project, most project system hierarchies (not all) implement IVsBuildPropertyStorage.Simon Mourier
@SimonMourier: No- I'm handling non-persistent data. Sorry, that's not very clear.Puppy

2 Answers

0
votes

I found a way to convince MEF to honour my static imports, so for now, I'm just using some static data.

(Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel).DefaultCompositionService.SatisfyImportsOnce(this);

It was posted somewhere else- maybe even on SO- took me a while to find it though. Note that this has no interface required- reflection is used, so it should be valid for any this.

0
votes

If I understand your question correctly, you can create a stub class that you do the exports from, instead of trying to force your static classes to export.

public class HostClass
{
   public static string StaticString
   { get  { return "string value"; } }
}

public class HostClassStub
{
   [Export("StaticStringValue", typeof(string))]
   public string StaticString
   { get { return HostClass.StaticString; } }
}

You may also consider just making your static class un-static, if that's an option for you. Remember, that by default MEF imports are singletons, so it should be just like having a global set of variables for each project that does the import.

I know this doesn't address the VS Extensions aspect of your problem, but I haven't dealt with those. Maybe this'll give you a path to your solution, though.