Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Costura for an SDK #27

Closed
GeertvanHorrik opened this issue Aug 29, 2013 · 12 comments
Closed

Costura for an SDK #27

GeertvanHorrik opened this issue Aug 29, 2013 · 12 comments
Assignees

Comments

@GeertvanHorrik
Copy link
Member

I am having troubles getting it to work ATM.

I have this setup:

  1. SDK (Orchestra => https://github.com/Orcomp/Orchestra), uses costura
  2. Some app that only references a single assembly

In the app (no 2), I get issues that Fluent cannot be loaded. However this is available in the SDK (1), packaged by costura.

I expected this (in the SDK) to work:

public static void Attach()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyLoader.ResolveAssembly);
}

But it seems not?

@ghost ghost assigned distantcam Aug 30, 2013
@distantcam
Copy link
Member

Is app 2 using fluent directly?

Costura uses the module initializer to hook itself up. If the module is not initialized before you try to use a reference to Fluent then the AssemblyResolve is not attached properly.

To fix this you just need to invoke the module initializer. Here are the ways I know how, assuming Foo is a type from the parent library.

  • Create a new instance => new Foo();
  • Reference a static field or property => var temp = Foo.Constant;
  • Get a type from the library => var temp = typeof(Foo);

@GeertvanHorrik
Copy link
Member Author

That's what I am doing, trying to load a type that not directly requires this assembly and wrote the name to console:

Console.WriteLine(typeof(Foo).Name);

However, it might be a good feature to have something like: CosturaInitializer.Force();

@distantcam
Copy link
Member

At first I thought that was a good idea too, but there's a few issues.

  • What namespace would CosturaInitializer have?
  • If it doesn't have a namespace, what will happen when you use 2 libraries that use Costura?
  • The Force() method would be empty, as just calling it would trigger the module initializer. So it makes more sense for the library maintainer to include a Library.Initialize call instead.
  • I doubt this scenario will occur too often. You're using an internal reference because you know about it, but normally a Costura wrapped assembly won't advertise which libraries it has embedded.
  • Costura was designed for exe's, not dll's. It can work with libraries but you have to know what you're doing, and to know tricks like forcing a module init if you use a reference before the main library.

@GeertvanHorrik
Copy link
Member Author

Good thoughts ;-)

  1. Default namespace of app
  2. Same as with ModuleInitializer (has no namespace) => user error if you don't change this, but won't break anything
  3. Ok, we can discuss the naming, but I think this can be added automatically (by weaving) or as a template (like ModuleInit)
  4. Yeah, I have hit this a few times now
  5. I know, but it works great for libraries that abstract away the internals. For example, in Orchestra you never use Fluent directly (so we are free to replace it by another product, which actually happened already once)

@distantcam
Copy link
Member

  1. Default namespace of app

The default namespace of the app is a setting in the project, and isn't transferred to the assembly, so Costura won't know it.

Without a namespace if 2 costura libraries include the same type then one of the references has to have a different alias because the fully qualified name will be the same. http://msdn.microsoft.com/en-us/library/ms173212.aspx

Why are you using Costura to embed referenced assemblies for libraries? Why do you need to package everything into one dll?

If you're using Costura to abstract away internals, then why are you directly accessing those internals? Surely instead of accessing the internal you should be accessing your library that has hidden the internals anyway.

@GeertvanHorrik
Copy link
Member Author

We provide a way to use the orchestra (like a VS shell). I don't want users to have to download every external component we use. So everything that isn't required explicitly by the user is packed into the assembly so we can distribute a single assembly instead of a list of packages.

@distantcam
Copy link
Member

Orchestra isn't available through nuget?

@GeertvanHorrik
Copy link
Member Author

Of course it is, but some of it's components not / contains bugs we need to hotfix because authors are too slow.

@distantcam
Copy link
Member

Ok. You could include the hotfix versions in your Orchestra nuget package, instead of using Costura.

It's easier for you to decide on a name for the initialize type and method and add it to Orchestra than for Costura to add it and potentially have that name collide across multiple projects.

I'd be interested in the all-father @SimonCropp's opinion. Can Fody get the default namespace for a project? Is that the correct way to go?

@SimonCropp
Copy link
Member

Can Fody get the default namespace for a project

not at the metadata level. So if is really needed perhaps pass the project file path to the weaver?

@GeertvanHorrik
Copy link
Member Author

Hmmm, passing in the project name might be interesting anyway (never know where you need it for, and won't hurt either).

@GeertvanHorrik
Copy link
Member Author

It looks lik the IncludeAssemblies works correctly, I will close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants