I am using AutoMapper in a distributable C# DLL for my ORM logic.
This DLL is consumed by different development teams for the web projects. Some of these web projects are MVC and some are web forms.
If there a way to have my DLL ensure that all the mappings have been register on application-start without having each team put the calls in their global files?
I have profiles all setup, but want this step to be hidden and always done.
Thanks
The only thing I can think of is to have a static constructor for a class in your dll where you will initialize automapper.
public class MyOrmClass
{
public static MyOrmclass()
{
//initialize automapper
}
}
I have an open source library that might help you with it, but you might have to do some small changes on each client
Related
I've been using this blog example:
http://blog.longle.net/2012/03/29/building-a-composite-mvc3-application-with-pluggable-areas/
I have the concepts working in my solution. However, I'm trying to figure out a good way only add bindings to the kernel if a user has permissions to access a module/area.
I've read up some on the ServiceLocator but I was trying to stay away from it.
One thing I'm trying just to get things to work is user Contructor injection in the default constructor for a module. It's working but is a hack.
The pattern I'm using, each module project you create an class that inherits from AreaRegistion. When each module project builds, relevant files are copied to the Areas folder of the main web project. Then when the main project loads, reflection is used to load all module assemblies. Then when AreaRegistration.RegisterAllAreas() is called, it detects and loads all the modules with a class that inherits AreaRegistration.
I'd like to figure out an good way to access the Ninject kernel and add bindings in the module class that inherits from AreaRegistration. I would imagine initiating code to add bindings from the RegisterArea() override.
I'm looking for any suggestions on how to do this without resorting to the ServiceLocator.
Any ideas would be greatly appreciated.
For now I've found a better solution and that's to use NinjectModule. In the Plugin class, I'm going to create a class which inherits from NinjectModule. Then setup the pluging bindings in the Load overload.
Then use Kernel.Load in my main app bootstrapper to initialize the Load overloads in all plugin classes which inherit from NinjectModule.
Is it possible using EF6 Code First and MVC5 to put all the models, views, and controllers that involve ASP.Identity into its own class library project. So that over multiple web applications you could use that same DLL and already have all the views / controllers / models and be using the same security database for multiple applications?
We have several web applications with separate databases and one security database that handles all of them, and we weren't sure how to keep this model now that we're moving to EF6 Code First and MVC5.
If it is possible could someone point me to a tutorial of something similar or give me a basic outline of steps to go through?
Or if there is a better way to achieve my goal, of having one set of code to handle ASP.NET-Identity security that I can plug that dll into multiple web applications and get the same logic and databases?
Or is this not a good idea in general?
Very open to suggestion and advice. I appreciate it.
Yes it is. We do this with every project that we have. The structure is very simple. Just create a class library project to your solution, add EF to the project, then reference the class library from your main project.
If using Code First Migrations be sure to select the class library project as the default project in the Package Manager console when running migrations or adding migrations.
Here is a pseudo solution structure for your solution
MySolution
- MyWebApp
reference: MyDAL
-MyDAL
reference: EF6
The advantage that I find to this is that you can then reference the "DAL" class library from say a companion console application or windows form application, or a companion website, even in a different solution, and they will use the same code base.
For example:
MySolution
- MyWebApp
reference: MyDAL
- MyDAL
reference: EF6
- MyOtherWebApp
reference: MyDAL
NOTE: Your data context will look for its connection string in the Web.config or App.config in the startup project. NOT the class library. This can be confusing at first... But once you think about how .NET compiles the application together into the final package, it makes sense.
If you're talking about creating one class library for an entire data layer shared between multiple projects, then that's easy enough. You can move all your models, your context, etc. into a class library and run migrations using the class library project. The other projects will just reference that class library and not have migrations of their own.
However, if you're talking about multiple databases and associated data layers, where project Foo has its own models, context and migrations and project Bar has its own models, context and migrations, while the class library has just the IdentityUser and IdentityDbContext, things get a little more complicated. You won't be able to combine any of these contexts. So in your Foo project you'd have to instantiate your context for Foo and your Identity context if you need to work with both. It's not a problem, per se, but it's something to be aware of.
I'm having an issue activating the IMvxMessenger using IoC. (Mac, Xamarin Studio, iOS7, Mono 3.2)
I have downloaded NPlus1DaysOfMvvmCross and loaded the N37 Maps project.
Compiled the project and it works fine.
I then added the Cirrious.MvvmCross.Plugins.Messenger.dll to the project and the following code to the app.cs Initialize just below the service IoC call.
CreatableTypes (typeof(IMvxMessenger).Assembly).AsInterfaces ().RegisterAsSingleton ();
I receive and error when compiling that says:
Failed to resolve parameter for parameter id of type Guid when creating Cirrious.MvvmCross.Plugins.Messenger.MvxSubscriptionToken
IMvxMessenger is a plugin and does not need to be registered for IoC in the way you are doing it. Plugins get registered by creating a bootstrap class for each of the plugins you want to use in your project like so:
public class MessengerPluginBootstrap
: MvxPluginBootstrapAction<Cirrious.MvvmCross.Plugins.Messenger.PluginLoader>
{
}
Some plugins with platform dependent parts, such as the Visibility Plugin, need to be registered in a different manner on iOS, because it is silly:
public class VisibilityPluginBootstrap
: MvxLoaderPluginBootstrapAction<Cirrious.MvvmCross.Plugins.Visibility.PluginLoader, Cirrious.MvvmCross.Plugins.Visibility.Touch.Plugin>
{
}
This way you should be able to use the types inside of the Plugin using IoC.
This doesn't sound like it's anything to do with ios7
The line of code
CreatableTypes(typeof(IMvxMessenger).Assembly)
.AsInterfaces()
.RegisterAsSingleton ();
will:
take all the creatable types in the assembly (ie any non-abstract types with a public constructor)
will then find their interfaces
will then create a new instance and register that as the singleton implementation for the interfaces.
For the Messenger plugin, that includes trying to new and register an MvxSubscriptionToken as an IDisposable singleton - although this fails as the public constructor for MvxSubscriptionToken requires a Guid (and you haven't told MvvmCross how to supply that - so the construction fails)
If you did want to just register specific types in an Assembly, then normally you'd add a EndingWith("PostFix") clause - like the default Mvx nuget templates do with Services as the postfix.
If you did want to just register a single specific class from an Assembly, then you'd often just do that as:
Mvx.RegisterSingleton<IThing>(new Thing());
However, for plugins - which are just a convention-based set of rules placed on top of IoC - what you normally want to do is to call EnsureLoaded() on the plugin manager for the PluginLoader for that plugin.
The easiest way to do that is to include a Bootstrap file in the UI project - see the examples in N=8 - https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-09-Location%20And%20Message/Location.Touch/Bootstrap - your application's Setup will use Reflection to find that Type and will then call EnsureLoaded on the plugin for you.
For more on IoC in MvvmCross, see https://github.com/slodge/MvvmCross/wiki/Service-Location-and-Inversion-of-Control
For more on plugins, see https://github.com/slodge/MvvmCross/wiki/MvvmCross-plugins
Make sure the plugin is installed in the Core project AND the Android project.
I am creating a series of related plugins. Each plugin is for a different entity. Does each plugin have to have it's own assembly? I'm using Visual Studio and I created a second project within the same solution but I can't see the new step in registration tool.
Thanks
It can do, but doesn't have to. That is pretty much your design decision. Consider if you had several classes all implementing IPlugin
public class MyFirstPlugin : IPlugin
{
//implemented as per usual
}
public class MySecondPlugin : IPlugin
{
//implemented as per usual
}
If you were to register that DLL in the plugin registration tool, you would see the following structure:
- Server
- DLL
- MyFirdtPlugin
- MySecondPlugin
You can then add steps to each plugin as desired.
The alternative would be to have one plugin per DLL, which would give you
- Server
- DLL1
- MyFirstPlugin
- DLL2
- MySecondPlugin
I must admit it seems like overkill - but it can also depend on how you are using your solutions.
In addition to glosrob's answer, I'm guessing that you're using the plugin registration tool to register your plugin. If so, you'll need to make sure that after you add your new plugin to the same dll, that you update the plugin dll itself with the registration tool, so you can register the new plugin method that you've created.
Yes, you can create each plugin in a different class library project but this is not a good practice. I'd prefer to collect all plugins into one class library.
Note that after selecting your assembly from the File Dialog you have to click on Load Assembly button to load all classes which implement the IPlugin interface.
To answer the question - no, each new plugin doesn't have to be contained in a new assembly.
To elaborate - it's technically possible to put in all the plugin code in just one project and a single file.
To warn - the above would be a nightmare to manage with all the ifs and buts, so it's a good example of can-but-shouldn't.
To suggest - I usually have a separate project for each entity's plugin and handle all the messages using a switch. On occasion, I might have two or three assemblies but you'll know when it's time to do so as you get there. Usually, one DLL is just enough.
Can I use CustomActionAttribute in classes that inherit from System.Configuration.Install.Installer? I want my class library to support both WiX and Visual Studio setup project.
I don't see any immediate reason why you couldn't do this. One obstacle is that Wix managed CA functions must be declared public static, so you would probably need to refactor most of your logic into functions that could be called by both your Install/Uninstall functions as well as your Wix CAs functions.
If you were to do this I would recommend creating the project from the Votive Managed Custom Action template in Visual Studio and then manually adding a Installer Class to the project. You can then define static functions in the installer class that can be exposed as CAs using the CustomAction attribute.
The reasons for not doing it are:
you can't have methods with same names in your custom actions assembly custom action method calls in WiX
And the DTF methods and VS setup project methods are different in signature.
Also, as I've understood, VS setup project CAs don't use Session object, unlike DTF CAs.