Named singleton instance in StructureMap (Multiple nHibernate session factories) - nhibernate

I have a scenario where I have two Nhibernate SessionFactorys I need to register an use with StructureMap. Only Foo needs mySessionFactory sessions.
Like this:
For<ISessionFactory>().Singleton().Use(NHibernateConfiguration.GetDefaultSessionFactory());
For<ISession>().HybridHttpOrThreadLocalScoped().Use(x => x.GetInstance<ISessionFactory>().OpenSession());
For<ISessionFactory>().Singleton().Use(AnotherNHibernateConfiguration.GetDefaultSessionFactory).Named("mySessionFactory");
For<ISession>().HybridHttpOrThreadLocalScoped().Use(x => x.GetInstance<ISessionFactory>("mySessionFactory").OpenSession()).Named("mySession");
For<Foo>()
.Use<Foo>()
.Ctor<ISession>("session").Is(x => x.TheInstanceNamed("mySession"));
The problem is that mySessionFactory is now used everywhere when I only wanted to to be used in Foo and everywhere else should use my unnamed instance.
What I'm I doing wrong?

On both your named instances, change Use to Add. Use sets that instance as the default as well as adding it as an instance. You could also reverse the order of your config (the last instance of a type added with Use will become the default), but using the Add method is much more explicit.

Related

Nhibernate Evers, how to change AuditJoinTable name

i'am using fluent Nhibernate and Envers with this setup
var enversConf = new NHibernate.Envers.Configuration.Fluent.FluentConfiguration();
enversConf.Audit<Segnalazione>()
IRevisionListener revListner = services.GetService<IRevisionListener>();
enversConf.SetRevisionEntity<RevisionEntity>(e => e.Id, e => e.RevisionDate, revListner);
cfg.SetEnversProperty(ConfigurationKey.AuditTableSuffix, "_LOG");
cfg.SetEnversProperty(ConfigurationKey.AuditStrategy, typeof(CustomValidityAuditStrategy));
cfg.IntegrateWithEnvers(enversConf);
i need to change AuditJoinTable naming adding a prefix XXX_
All others table have same prefix and so standard logging table inherits it, only JoinTable hasn't it
i found settings for java version but not for .net one
EDIT:
Now i have table with this naming convention:
XXX_Table1
XXX_Table2
main log table are create with _LOG suffix, so i get
XXX_Table1_LOG
XXX_Table2_LOG
while
AuditJoinTable are created as
Table1Table2_LOG
and i need
XXX_Table1Table2_LOG
I am solving this by adding the name to each join table. Could be more generic but it works.
enversConf.Audit<Segnalazione>()
.SetTableInfo(ug => ug.Foo, t => t.TableName = "XXX_Segnalazione_Foo")
Do you mean that cfg.SetEnversProperty(ConfigurationKey.AuditTablePrefix, "XXX_") doesn't work? It should.
IEnversNamingStrategy is used to decide names for tables, default this one is used where ConfigurationKey.AuditTablePrefix is used for "default prefix". You can also inject your own impl of this interface if you want to.
Using SetTableInfo overrides this and surely works but if I understand you correctly you don't need to do that in this case.

.net core Options configuration array override

I have a class with one List<string> variable having default values.
public class MyOptions{
public List<string> Settings {get; set;} = new List<string>(){"Controls","Menus"};
}
Then I register it in ConfigureServices method like
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
I want to be able to change the value of Settings collection without changing the code.
In my appsettings.json, I have tried the following
{
"MyOptions":{
"Settings:0":"ReplacedSettings"
}
}
to replace "Controls" with "ReplacedSettings", but it doesn't work and I now get Settings with three values instead ["Controls","Menus","ReplacedSettings"]
whereas I want ["ReplacedSettings","Menus"].
Is this supported? Or is there any similar data structure I can with Option pattern that allows defaults values to be overridden from appsettings.json.
Thanks.
This behavior is by design because when binding to collections in options, the values will be appended. The reason why you cannot overwrite the default values from your MyOptions options model is that options and configuration are actually two distinct concepts which can work together but don’t have to. I go into more detail in an answer to a related question but basically handling the configuration and binding the configuration to options objects are two separate things.
When you just look at your configuration, then there’s the following value:
MyOptions:Settings:0 => "ReplacedSettings"
The configuration system does not know about your "Controls" and "Menus" values. Those only exist in the options type you later bind to. So because there is nothing else in the configuration, there is nothing you can replace here. And when the binder then uses the configuration to set up the options types, it will just append that single value "ReplacedSettings" to the list.
If you want to make sure that you can replace values, then you will have to declare those settings in configuration:
MyOptions:Settings:0 => "Controls"
MyOptions:Settings:1 => "Menus"
If you now apply the configurations with your "ReplacedSettings", then it will properly replace the one matching key and leave the other:
MyOptions:Settings:0 => "ReplacedSettings"
MyOptions:Settings:1 => "Menus"
The common solution for this is to use the appsettings.json for default values. That way, you can overwrite those with an environment-specific appsettings.<env>.json or some other source (e.g. environment variables) and apply your overrides. Of course, you shouldn’t specify the defaults in your options type then.

ContentHandler issues (circular reference) in Orchard

crosspost: https://orchard.codeplex.com/discussions/459007
First question I have is what would be the repercussions of having 2 PartHandlers for the same Part in 2 different modules?
I got into this predicament because I have to run a method once a specific Content Type is created. It would be as easy to hook onto OnCreated for the part, however, here is my scenario:
Module A contains the part and the original handler
Module B contains the service where the method is
Module B has a reference to Module A
Therefore, I am unable to reference Module B within Module A (circular reference). So what I did was to copy the exact same PartHandler in Module A and placed it in Module B.
Would anything be wrong with that?
Then comes my second question, which I think could solve all these problems: Can we create a PartHandler for the Content Item's default Content Part? (i.e. the part where all custom fields are attached to)
This would definately make things easier as I could consolidate stuff that need to run there.
UPDATE 1 (to better explain question 2)
ContentDefinitionManager.AlterPartDefinition("EventItem",
builder => builder
.WithField("StartDate", cfg => cfg
.OfType("DateTimeField")
.WithDisplayName("Start Date")
.WithSetting("DateTimeFieldSettings.Display", "DateOnly")
.WithSetting("DateTimeFieldSettings.Required", "true"))
.WithField("StartTime", cfg => cfg
.OfType("DateTimeField")
.WithDisplayName("Start Time")
.WithSetting("DateTimeFieldSettings.Display", "TimeOnly"))
.WithField("EndDate", cfg => cfg
.OfType("DateTimeField")
.WithDisplayName("End Date")
.WithSetting("DateTimeFieldSettings.Display", "DateOnly"))
.WithField("EndTime", cfg => cfg
.OfType("DateTimeField")
.WithDisplayName("End Time")
.WithSetting("DateTimeFieldSettings.Display", "TimeOnly"))
.WithField("Intro", cfg => cfg
.OfType("TextField")
.WithDisplayName("Intro")
.WithSetting("TextFieldSettings.Flavor", "textarea"))
ContentDefinitionManager.AlterTypeDefinition(
"EventItem"
, cfg =>
cfg
.DisplayedAs("Event Item")
.WithPart("TitlePart")
.WithPart("EventItem")
.WithPart("LocationPart")
.WithPart("AutoroutePart", builder => builder
.WithSetting("AutorouteSettings.AllowCustomPattern", "true")
.WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false")
.WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: 'learn/events/{Content.Slug}', Description: 'learn/events/event-title'}]")
.WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
.WithPart("CommonPart")
.Draftable()
.Creatable()
);
I'm talking about creating a ContentHandler for the EventItem part which holds all the custom fields. How can I go about it when EventItemPart is not defined in any class in the solution?
The following below won't work since it can't find the class EventItemPart:
OnCreated<EventItemPart>((context, keynotes) =>
questionService.SetDefaultQuestions(context.ContentItem));
Cross-answer as well.
Bertrand's perfectly right. Why do you need to reference B in A in first place? If the service from B needs A and A needs this service, then it belongs to A (at least the interface - contract).
You can always split interface and actual implementation for your service, having one in different module than another. If implementation of your service requires stuff from B, then put the interface in A, but actual implementation in B. This way A doesn't even need to know about the existence of B, but still be able to use the service via it's interface - it's the beauty of IoC pattern and Orchard modularity:)
You may use ContentPart or IContent as a type argument in handler generic methods. It's perfectly valid. This way you'd be able to plug in to events on all items, and perform custom filtering afterwards (based on type name, some field existence etc.). In your case it may look like:
OnCreated<ContentPart>((context, part) =>
{
if(part.ContentItem.ContentType != "EventItem") return;
questionService.SetDefaultQuestions(context.ContentItem);
});
Update: no need to do this: .WithPart("EventItem"). This 'fake' part will be automatically added by framework.
Cross-answer:
none
However, repeating yourself is almost always wrong, especially if it's done for a bad reason. Why is are the service and the part in two different modules? Why does A need B? A circular reference indicates tight coupling. If the tight coupling is justified, then it should happen in a single module. If it's not, then you need to re-do your design to remove it.
You can create a handler for anything, but your explanation of your scenario is way to vague and abstract to give any useful advice.

Ninject - How to dynamically select an implementation to bind to an interface

I'm currently using Ninject to create instances of interfaces in a WCF Services application.
Bind<IObjA>().To<ObjA>().InRequestScope();
Bind<IObjB>().To<ObjB>().InRequestScope();
Bind<IObjC>().To<ObjC>().InRequestScope();
It works great, but we are going to have several implementations of IObjC. What options do I have for continuing fluid assignment of implementation to interface for IObjA/IObjB but allowing for configurable assignment for IObjC?
I found a related question on SO but I don't know if I can support both a fluid and a configurable approach simultaneously.
For example, can I use Ninject.extensions.xml for IObjC while continuing to use the above approach for IObjA and IObjB?
Is it advisable to have conditional assignment for IObjC? That seems dirty but at the same time appears very simple.
if (condition1)
Bind<IObjC>().To<ObjC1>().InRequestScope();
else if (condition 2)
Bind<IObjC>().To<ObjC2>().InRequestScope();
Also, I know other frameworks like Castle support XML configuration but I would like to continue using Ninject.
1 - your bindings to IObjC have nothing to do with any other bindings. it doesn't matter where, when, or how you bind other services.
2 - you can use the XML extensions, but I would ask why you think you need it to be configurable.
3 - there are 2 possibilities for your conditional. first is that you want to make a decision at startup to determine whether to use ObjC1 for the entire lifetime of the app, or ObjC2. if that's the case, your code is ok. however, if you want to dynamically decided which object to use each time you resolve the binding, you will need to put the condition inside your binding, like so:
Bind<IObjC>().ToMethod( ctx => condition ? ctx.Kernel.Get<ObjC1>() : ctx.Kernel.Get<ObjC2>() );
alternately, you can use Named bindings:
Bind<ILog>().ToConstant( LogManager.GetLogger( "Accounting" ) ).Named( "Accounting" );
or "When" conditions to help:
Bind<ILog>().ToConstant( LogManager.GetLogger( "Background" ) ).When( context => context.Target != null && context.Target.Name == "backgroundLogger" );

Fluent NHibernate LazyLoad Issues

I couldn't find an answer to this issue so I assume it is something I am doing wrong.
I have a PersistenceModel set up where I have set a convention as follows: -
persistenceModel.Conventions.Add(DefaultLazy.Always());
However, for one of the HasManyToMany relationships in one of my entities I want eager loading to take place which I am setting up as follows: -
HasManyToMany(x => x.Affiliates).Not.LazyLoad();
Intuitively, I expect eager loading to take place as I am overriding the lazy load default that I have specified as a convention but it still lazy loads. If I set the DefaultLazy convention to never and then set LazyLoad on an individual relationship it doesn't work either.
Any ideas?
When you set Not.LazyLoad(), you tell NHibernate to load Affiliates when the parent loads. NHibernate will do this by performing another select on the Affliates many-to-many table regardless of whether you access the Affiliates collection or not. NHibernate is using another select because that is the default fetching mode. You want to override fetching mode as well, either in the query or in the mapping. To do it in the mapping, add the following:
HasManyToMany(x => x.Affiliates)
.Not.LazyLoad()
.Fetch.Join();
You might also want to include a ".Cascade.AllDeleteOrphan()" if you want NHibernate to persist new Affiliaites added to the collection and delete orphaned ones. If you do not do this, you will have to explicitly call session.Save(newAffiliate). Otherwise you'll receive a TransientObjectException when your Affiliates collection contains a new Affiliate.
It may be one stupid thing to ask, but have you execute the query inside your session? Say,
Using(var session = OpenSession())
{
session.Query<Entity>().ToList();
}
I had this problem before, and finally realized the objects that I was accessing hadn't been queried before disposing the session.