Personally, I think it’s better to build your content separately via the MonoGame Pipeline Tool, so that you’re always aware of exactly what it’s doing. You could use the steps below and still setup something in your .csproj file to build the content at compile time if you believe it’s necessary.
At any rate, this would involve a couple steps. First, the out-of-the-box content object in MonoGame is designed to read from file resources, so you’ll need to extend the class with something like this to read from embedded resources instead (untested code):
using System;
using System.Linq;
using System.Reflection;
using System.IO;
using Microsoft.Xna.Framework.Content;
namespace MyGameNamespace
{
public class MyContentManager : ContentManager
{
private Assembly assembly = Assembly.GetExecutingAssembly();
private string[] resourceNames = assembly.GetManifestResourceNames();
public MyContentManager(IServiceProvider serviceProvider)
: base(serviceProvider)
{
}
public MyContentManager(IServiceProvider serviceProvider, string rootDirectory)
: base(serviceProvider, rootDirectory)
{
}
protected Stream GetResourceStream(string assetName)
{
try
{
Stream stream = assembly.GetManifestResourceStream(assetName);
if (stream == null)
throw new ContentLoadException("Resource not found");
return stream;
}
catch (Exception exception)
{
throw new ContentLoadException("Error loading resource");
}
}
protected override Stream OpenStream(string assetName)
{
return GetResourceStream("MyGameNamespace.Content." + assetName.Replace('\\', '/').Replace('/', '.') + ".xnb");
}
public string GetResourceText(string embeddedResourceAssetName)
{
using (Stream stream = GetResourceStream(embeddedResourceAssetName))
{
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
public bool HasResource(string embeddedResourceAssetName)
{
return resourceNames.Contains(embeddedResourceAssetName);
}
public string[] GetResourceNames()
{
return resourceNames;
}
}
}
Instead of using the out-of-the-box Game1.Content reference, you’d need to make a reference to this new class and make sure to implement its disposal. So, that would look something like putting this in the constructor of your game:
myContentManager = new MyContentManager(Services);
and this in your main game class:
// necessary since we're not using MonoGame's generic "Content" property - so we need to make sure our custom one hits its Dispose call as well
protected override void Dispose(bool disposing)
{
content.Dispose();
content = null;
base.Dispose(disposing);
}
You could then use this new object in the same way as your default content loading:
Texture2D myImage = myContentManager.Load<Texture2D>("images/someCompiledImageAsset");
Now, you’d need to replace your actual Content.mgcb reference with something else that will collect your built content (XNBs and other files created by the MonoGame Pipeline Tool). To do this, remove your Content.mgcb reference from your project, and then edit your .csproj to include something like this:
<EmbeddedResource Include="..\..\MyGameProject\Content\bin\Windows\**\*.*">
<Link>Content\%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>
It’s worth noting, that using a method like this, you’d need to reload your project (or VS) anytime you’ve added or removed a content file, since VS collects the files to be embedded at project load time.
Also noteworthy, in many cases, choosing to embed your content into your executable will often cause performance/loading issues.
Hopefully this will give you a good jump-start on using embedded content with MonoGame 