Computed properties in a PageModel - asp.net-core

I have a subclass of PageModel that looks like this:
public class DetailsModel : PageModel
{
...
public IList<Comment> Comments { get; set; }
...
public async Task<IActionResult> OnGetAsync(int? id)
{
Comments = await _context.Comment.Where(comment => comment.LinkId == id).ToListAsync();
...
}
...
}
Moving the code to the property definition
Instead of computing the property value inside OnGetAsync, I had considered having the computation code be at the property definition site:
public IList<Comment> Comments
{
get
{
return _context.Comment.Where(comment => comment.LinkId == Link.Id).ToList();
}
}
One downside there is that the code is no longer async.
The code runs each time the property is called (which may or may not be desired).
Putting the code in a method
Finally, I can put the code in a method instead of a property:
public async Task<IList<Comment>> Comments()
{
return await _context.Comment.Where(comment => comment.LinkId == Link.Id).ToListAsync();
}
Now it's async again. But we have a little syntactic overhead at the callsite:
await Comments()
I.e. we need to use await and the parens.
Question
I like the second approach as the code is kept close to the property definition. This is especially nice when there are many properties. (It seems awkward to have a long list of property definitions only to set them up later in OnGet.) But as mentioned, there are a couple of potential downsides.
What is the idiomatic and recommended way to do something like this?

If you consider the .NET guidelines for property design, there are some relevant bits:
AVOID throwing exceptions from property getters
and
Property getters should be simple operations and should not have any
preconditions. If a getter can throw an exception, it should probably
be redesigned to be a method.
Generally properties should be simple and performant, otherwise a method is a better choice. Using a method also gives you control over exactly when it is invoked, which is more difficult with properties that execute on access.
In this case, it would be ideal to keep any queries etc in the OnGetAsync where you and others expect to find it, and certainly to keep it on an async path.

Related

AsyncLocal<T> doesn't reach controllers

I don't quite fully understand this situation, where AsyncLocal instance is set at a certain point in the AuthenticationHandler, but does not reach the controller, when it is injected into the constructor.
I've made it similar to how IHttpContextAccessor works, but still nowhere near. However, if I set the AsyncLocal from a Middleware, it reaches the controller. Also, setting the HttpContext.Items property from AuthenticationHandler works just fine.
Question: How is HttpContext able to retain Items property contents all the way, and is ASP.NET runtime disposing the captured ExecutionContext of my DomainContextAccessor for some security reason because of where it is being set at?
I've made a sample app to demo this use case. I'd really appreciate someone shedding the light on this problem.
You already have a good answer on "how should I fix this?" Here's more of a description of why it's behaving this way.
AsyncLocal<T> has the same semantics as logging scopes. Because it has those same semantics, I always prefer to use it with an IDisposable, so that the scope is clear and explicit, and there's no weird rules around whether a method is marked async or not.
For specifics on the weird rules, see this. In summary:
Writing a new value to an AsyncLocal<T> sets that value in the current scope.
Methods marked async will copy their scope to a new scope the first time it's written to (and it's the new scope that is modified).
I've made it similar to how IHttpContextAccessor works, but still nowhere near.
I don't recommend copying the design of IHttpContextAccessor. It works... for that very specific use case. If you want to use AsyncLocal<T>, then use a design like this:
static class MyImplicitValue
{
private static readonly AsyncLocal<T> Value = new();
public static T Get() => Value.Value;
public static IDisposable Set(T newValue)
{
var oldValue = Value.Value;
Value.Value = newValue;
return new Disposable(() => Value.Value = oldValue);
}
}
usage:
using (MyImplicitValue.Set(myValue))
{
// Code in here can get myValue from MyImplicitValue.Get().
}
You can wrap that into an IMyImplicitValueAccessor if desired, but note that any "setter" logic should be using the IDisposable pattern as shown.
AsyncLocal instance is set at a certain point in the AuthenticationHandler, but does not reach the controller
That's because your AuthenticationHandler sets the value but doesn't call the controller after setting that value (and it shouldn't).
However, if I set the AsyncLocal from a Middleware, it reaches the controller.
That's because middleware is calls the next middleware (eventually getting to the controller). I.e., middleware is structured like this:
public async Task InvokeAsync(HttpContext context)
{
using (implicitValue.Set(myValue))
{
await _next(context);
}
}
So the controllers are in the scope of when that AsyncLocal<T> value was set.
How is HttpContext able to retain Items property contents all the way
Items is just a property bag. It doesn't have anything to do with AsyncLocal<T>. It exists because it's a property on HttpContext, and it persists because the same HttpContext instance is used throughout the request.
is ASP.NET runtime disposing the captured ExecutionContext of my DomainContextAccessor for some security reason because of where it is being set at?
Not exactly. The AsyncLocal<T> is being set just fine; it's just that the controllers are not called within the scope of that AsyncLocal<T> being set.
So what must be happening is there is a execution context change which wipes that value out. It works with in the middleware because your controller is in the same execution context as your middleware.
Change your code to this:
private static void DomainContextChangeHandler(AsyncLocalValueChangedArgs<DomainContextHolder> args)
{
Trace.WriteLine($"ThreadContextChanged: {args.ThreadContextChanged}");
Trace.WriteLine($"Current: {args.CurrentValue?.GetHashCode()}");
Trace.WriteLine($"Previous: {args.PreviousValue?.GetHashCode()}");
Trace.WriteLine($"Thread Id: {Thread.CurrentThread.ManagedThreadId}");
}
Now you can see when the context changes.
Here is something you could do:
private static void DomainContextChangeHandler(AsyncLocalValueChangedArgs<DomainContextHolder> args)
{
if (args.ThreadContextChanged && (args.PreviousValue != null) && (args.CurrentValue == null))
{
Trace.WriteLine(
"***** Detected context change with a previous value but setting current " +
"value to null. Resetting value to previous.");
_domainContextCurrent.Value = args.PreviousValue;
return;
}
Trace.WriteLine($"ThreadContextChanged: {args.ThreadContextChanged}");
Trace.WriteLine($"Current: {args.CurrentValue?.GetHashCode()}");
Trace.WriteLine($"Previous: {args.PreviousValue?.GetHashCode()}");
Trace.WriteLine($"Thread Id: {Thread.CurrentThread.ManagedThreadId}");
}
But, that kinda defeats the purpose of using AsyncLocal as your backing store.
My suggestion is you drop the AsyncLocal and use normal class-scoped storage:
namespace WebApp.Models
{
public interface IDomainContextAccessor
{
DomainContext DomainContext { get; set; }
}
public sealed class DomainContextAccessor : IDomainContextAccessor
{
public DomainContext DomainContext { get; set; }
}
}
And inject it as scoped instead of singleton:
services.AddScoped<IDomainContextAccessor, DomainContextAccessor>();
It will do exactly what you want without any kludges -- AND, the future you (or devs) will absolutely understand what's going on and why it is the way it is.
No middleware, no AsyncLocal funny-business. It just works.
Your answer is here:
.net core AsyncLocal loses its value
In your DomainContextAccessor class when you set new value in this line: _domainContextCurrent.Value = new DomainContextHolder { Context = value };
you create NEW ExecutionContext in current thread and child threads.
So I suppose that mvc runs like this:
Middleware thread => you set value => some child thread with Controller execution which sees parent changes
But for UserAuthenticationHandler it feels it works like this:
Some controller factory creates controller with injected IDomainContextAccessor (1 context) => mvc executes auth handler in child task where you set value and create 2 context. But it's value does not go UP to parent (where controller 1 context exists) because you create new context when you set value. Even more your code gets parents context, gets reference to its value and makes property Context = null, so you will get null in Controller.
So to fix this you need to change your code:
public class DomainContext
{
private static AsyncLocal<DomainContext> _contextHolder = new AsyncLocal<DomainContext>();
public static DomainContext Current
{
get
{
return _contextHolder.Value;
}
}
public Job JobInfo { get; set; }
public static void InitContext()
{
_contextHolder.Value = new DomainContext();
}
}
//using in middleware:
DomainContext.InitContext();
//using in auth handler:
DomainContext.Current.JobInfo = ...
In example above you don't change DomainContext reference in _contextHolder.Value;
It remains the same but you only change value of JobInfo in it later in auth handler

Using Test Doubles with DbEntityEntry and DbPropertyEntry

I am using the new Test Doubles in EF6 as outlined here from MSDN . VS2013 with Moq & nUnit.
All was good until I had to do something like this:
var myFoo = context.Foos.Find(id);
and then:
myFoo.Name = "Bar";
and then :
context.Entry(myFoo).Property("Name").IsModified = true;
At this point is where I get an error:
Additional information: Member 'IsModified' cannot be called for
property 'Name' because the entity of type
'Foo' does not exist in the context. To add an
entity to the context call the Add or Attach method of
DbSet.
Although, When I examine the 'Foos' in the context with an AddWatch I can see all items I Add'ed before running the test. So they are there.
I have created the FakeDbSet (or TestDbSet) from the article. I am putting each FakeDbSet in the FakeContext at the constructor where each one gets initialized. Like this:
Foos = new FakeDbSet<Foo>();
My question is, is it possible to work with the FakeDbSet and the FakeContext with the test doubles scenario in such a way to have access to DbEntityEntry and DBPropertyEntry from the test double? Thanks!
I can see all items I Add'ed before running the test. So they are there.
Effectively, you've only added items to an ObservableCollection. The context.Entry method reaches much deeper than that. It requires a change tracker to be actively involved in adding, modifying and removing entities. If you want to mock this change tracker, the ObjectStateManager (ignoring the fact that it's not designed to be mocked at all), good luck! It's got over 4000 lines of code.
Frankly, I don't understand all these blogs and articles about mocking EF. Only the numerous differences between LINQ to objects and LINQ to entites should be enough to discourage it. These mock contexts and DbSets build an entirely new universe that's a source of bugs in itself. I've decided to do integrations test only when and wherever EF is involved in my code. A working end-to-end test gives me a solid feeling that things are OK. A unit test (faking EF) doesn't. (Others do, don't get me wrong).
But let's assume you'd still like to venture into mocking DbContext.Entry<T>. Too bad, impossible.
The method is not virtual
It returns a DbEntityEntry<T>, a class with an internal constructor, that is a wrapper around an InternalEntityEntry, which is an internal class. And, by the way, DbEntityEntry doesn't implement an interface.
So, to answer your question
is it possible to (...) have access to DbEntityEntry and DBPropertyEntry from the test double?
No, EF's mocking hooks are only very superficial, you'll never even come close to how EF really works.
Just abstract it. If you are working against an interface, when creating your own doubles, put the modified stuff in a seperate method. My interface and implementation (generated by EF, but I altered the template) look like this:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Model
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public interface IOmt
{
DbSet<DatabaseOmtObjectWhatever> DatabaseOmtObjectWhatever { get; set; }
int SaveChanges();
void SetModified(object entity);
void SetAdded(object entity);
}
public partial class Omt : DbContext, IOmt
{
public Omt()
: base("name=Omt")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<DatabaseOmtObjectWhatever> DatabaseOmtObjectWhatever { get; set; }
public void SetModified(object entity)
{
Entry(entity).State = EntityState.Modified;
}
public void SetAdded(object entity)
{
Entry(entity).State = EntityState.Added;
}
}
}

Do write-only properties have practical applications?

I don't know why I started thinking about this, but now I can't seem to stop.
In C# - and probably a lot of other languages, I remember that Delphi used to let you do this too - it's legal to write this syntax:
class WeirdClass
{
private void Hello(string name)
{
Console.WriteLine("Hello, {0}!", name);
}
public string Name
{
set { Hello(name); }
}
}
In other words, the property has a setter but no getter, it's write-only.
I guess I can't think of any reason why this should be illegal, but I've never actually seen it in the wild, and I've seen some pretty brilliant/horrifying code in the wild. It seems like a code smell; it seems like the compiler should be giving me a warning:
CS83417: Property 'Name' appears to be completely useless and stupid. Bad programmer! Consider replacing with a method.
But maybe I just haven't been doing this long enough, or have been working in too narrow a field to see any examples of the effective use of such a construct.
Are there real-life examples of write-only properties that either cannot be replaced by straight method calls or would become less intuitive?
My first reaction to this question was: "What about the java.util.Random#setSeed method?"
I think that write-only properties are useful in several scenarios. For example, when you don't want to expose the internal representation (encapsulation), while allowing to change the state of the object. java.util.Random is a very good example of such design.
Code Analysis (aka FxCop) does give you a diagnostic:
CA1044 : Microsoft.Design : Because
property 'WeirdClass.Name' is write-only,
either add a property getter with an
accessibility that is greater than or
equal to its setter or convert this
property into a method.
Write-only properties are actually quite useful, and I use them frequently. It's all about encapsulation -- restricting access to an object's components. You often need to provide one or more components to a class that it needs to use internally, but there's no reason to make them accessible to other classes. Doing so just makes your class more confusing ("do I use this getter or this method?"), and more likely that your class can be tampered with or have its real purpose bypassed.
See "Why getter and setter methods are evil" for an interesting discussion of this. I'm not quite as hardcore about it as the writer of the article, but I think it's a good thing to think about. I typically do use setters but rarely use getters.
I have code similar to the following in an XNA project. As you can see, Scale is write-only, it is useful and (reasonably) intuitive and a read property (get) would not make sense for it. Sure it could be replaced with a method, but I like the syntax.
public class MyGraphicalObject
{
public double ScaleX { get; set; }
public double ScaleY { get; set; }
public double ScaleZ { get; set; }
public double Scale { set { ScaleX = ScaleY = ScaleZ = value; } }
// more...
}
One use for a write-only property is to support setter dependency injection, which is typically used for optional parameters.
Let's say I had a class:
public class WhizbangService {
public WhizbangProvider Provider { set; private get; }
}
The WhizbangProvider is not intended to be accessed by the outside world. I'd never want to interact with service.Provider, it's too complex. I need a class like WhizbangService to act as a facade. Yet with the setter, I can do something like this:
service.Provider = new FireworksShow();
service.Start();
And the service starts a fireworks display. Or maybe you'd rather see a water and light show:
service.Stop();
service.Provider = new FountainDisplay(new StringOfLights(), 20, UnitOfTime.Seconds);
service.Start();
And so on....
This becomes especially useful if the property is defined in a base class. If you chose construction injection for this property, you'd need to write a constructor overload in any derived class.
public abstract class DisplayService {
public WhizbangProvider Provider { set; private get; }
}
public class WhizbangService : DisplayService { }
Here, the alternative with constructor injection is:
public abstract class DisplayService {
public WhizbangProvider Provider;
protected DisplayService(WhizbangProvider provider) {
Provider = provider ?? new DefaultProvider();
}
}
public class WhizbangService : DisplayService {
public WhizbangService(WhizbangProvider provider)
: base(provider)
{ }
}
This approach is messier in my opinion, because you need to some of the internal workings of the class, specifically, that if you pass null to the constructor, you'll get a reasonable default.
In MVP pattern it is common to write a property with a setter on the view (no need for a getter) - whenever the presenter sets it content the property will use that value to update some UI element.
See here for a small demonstration:
public partial class ShowMeTheTime : Page, ICurrentTimeView
{
protected void Page_Load(object sender, EventArgs e)
{
CurrentTimePresenter presenter = new CurrentTimePresenter(this);
presenter.InitView();
}
public DateTime CurrentTime
{
set { lblCurrentTime.Text = value.ToString(); }
}
}
The presenter InitView method simply sets the property's value:
public void InitView()
{
view.CurrentTime = DateTime.Now;
}
Making something write-only is usefulwhenever you're not supposed to read what you write.
For example, when drawing things onto the screen (this is precisely what the Desktop Window Manager does in Windows):
You can certainly draw to a screen, but you should never need to read back the data (let alone expect to get the same design as before).
Now, whether write-only properties are useful (as opposed to methods), I'm not sure how often they're used. I suppose you could imagine a situation with a "BackgroundColor" property, where writing to it sets the background color of the screen, but reading makes no sense (necessarily).
So I'm not sure about that part, but in general I just wanted to point out that there are use cases for situations in which you only write data, and never read it.
Although the .NET design guidelines recommend using a method ("SetMyWriteOnlyParameter") instead of a write-only property, I find write-only properties useful when creating linked objects from a serialised representation (from a database).
Our application represents oil-field production systems. We have the system as a whole (the "Model" object) and various Reservoir, Well, Node, Group etc objects.
The Model is created and read from database first - the other objects need to know which Model they belong to. However, the Model needs to know which lower object represents the Sales total. It makes sense for this information to be stored a Model property. If we do not want to have to do two reads of Model information, we need to be able to read the name of Sales object before its creation. Then, subsequently, we set the "SalesObject" variable to point to the actual object (so that, e.g., any change by the user of the name of this object does not cause problems)
We prefer to use a write-only property - 'SalesObjectName = "TopNode"' - rather than a method - 'SetSalesObjectName("TopNode") - because it seems to us that the latter suggests that the SalesObject exists.
This is a minor point, but enough to make us want to use a Write-Only property.
As far as I'm concerned, they don't. Every time I've used a write-only property as a quick hack I have later come to regret it. Usually I end up with a constructor or a full property.
Of course I'm trying to prove a negative, so maybe there is something I'm missing.
I can't stop thinking about this, either. I have a use case for a "write-only" property. I can't see good way out of it.
I want to construct a C# attribute that derives from AuthorizeAttribute for an ASP.NET MVC app. I have a service (say, IStore) that returns information that helps decide if the current user should be authorized. Constructor Injection won't work, becuase
public AllowedAttribute: AuthorizeAttribute
{
public AllowedAttribute(IStore store) {...}
private IStore Store { get; set; }
...
}
makes store a positional attribute parameter, but IStore is not a valid attribute parameter type, and the compiler won't build code that is annotated with it. I am forced to fall back on Property Setter Injection.
public AllowedAttribute: AuthorizeAttribute
{
[Inject] public IStore Store { private get; set; }
...
}
Along with all the other bad things about Property Setter instead of Constructor Injection, the service is a write-only property. Bad enough that I have to expose the setter to clients that shouldn't need to know about the implementation detail. It wouldn't do anybody any favors to let clients see the getter, too.
I think that the benefit of Dependency Injection trumps the guidelines against write-only properties for this scenario, unless I am missing something.
I just came across that situation when writing a program that reads data from a JSON database (Firebase). It uses Newtonsoft's Json.NET to populate the objects. The data are read-only, i.e., once loaded they won't change. Also, the objects are only deserialized and won't be serialized again. There may be better ways, but this solution just looks reasonable for me.
using Newtonsoft.Json;
// ...
public class SomeDatabaseClass
{
// JSON object contains a date-time field as string
[JsonProperty("expiration")]
public string ExpirationString
{
set
{
// Needs a custom parser to handle special date-time formats
Expiration = Resources.CustomParseDateTime(value);
}
}
// But this is what the program will effectively use.
// DateTime.MaxValue is just a default value
[JsonIgnore]
public DateTime Expiration { get; private set; } = DateTime.MaxValue;
// ...
}
No, I can' imagine any case where they can't be replaced, though there might people who consider them to be more readable.
Hypothetical case:
CommunicationDevice.Response = "Hello, World"
instead of
CommunicationDevice.SendResponse("Hello, World")
The major job would be to perform IO side-effects or validation.
Interestingly, VB .NET even got it's own keyword for this weird kind of property ;)
Public WriteOnly Property Foo() As Integer
Set(value As Integer)
' ... '
End Set
End Property
even though many "write-only" properties from outside actually have a private getter.
I recently worked on an application that handled passwords. (Note that I'm not claiming that the following is a good idea; I'm just describing what I did.)
I had a class, HashingPassword, which contained a password. The constructor took a password as an argument and stored it in a private attribute. Given one of these objects, you could either acquire a salted hash for the password, or check the password against a given salted hash. There was, of course, no way to retrieve the password from a HashingPassword object.
So then I had some other object, I don't remember what it was; let's pretend it was a password-protected banana. The Banana class had a set-only property called Password, which created a HashingPassword from the given value and stored it in a private attribute of Banana. Since the password attribute of HashingPassword was private, there was no way to write a getter for this property.
So why did I have a set-only property called Password instead of a method called SetPassword? Because it made sense. The effect was, in fact, to set the password of the Banana, and if I wanted to set the password of a Banana object, I would expect to do that by setting a property, not by calling a method.
Using a method called SetPassword wouldn't have had any major disadvantages. But I don't see any significant advantages, either.
I know this has been here for a long time, but I came across it and have a valid (imho) use-case:
When you post parameters to a webapi call from ajax, you can simply try to fill out the parameters class' properties and include validation or whatsoever.
public int MyFancyWepapiMethod([FromBody]CallParams p) {
return p.MyIntPropertyForAjax.HasValue ? p.MyIntPropertyForAjax.Value : 42;
}
public class CallParams
{
public int? MyIntPropertyForAjax;
public object TryMyIntPropertyForAjax
{
set
{
try { MyIntPropertyForAjax = Convert.ToInt32(value); }
catch { MyIntPropertyForAjax = null; }
}
}
}
On JavaScript side you can simply fill out the parameters including validation:
var callparameter = {
TryMyIntPropertyForAjax = 23
}
which is safe in this example, but if you handle userinput it might be not sure that you have a valid intvalue or something similar.

Property chaining in RhinoMocks

I have a class TxRx with a property called Common. Common then has a property called LastMod. I want to write a RhinoMock expectation to show that LastMod has been set with something. So I tried:
var txRx = MockRepository.GenerateMock<TxRx>();
var common = MockRepository.GenerateMock<Common>();
txRx.Expect(t => t.Common).Return(common);
txRx.Expect(t => t.Common.LastMod).SetPropertyAndIgnoreArgument();
But I get the following exception:
System.InvalidOperationException: Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
at Rhino.Mocks.LastCall.GetOptions[T]()
at Rhino.Mocks.RhinoMocksExtensions.Expect[T,R](T mock, Function`2 action)
at ...
I presume this means Common needs to be virtual, but as it is a property on a LinqToSql generated class I can't make it virtual (other than hacking the autogen code which is not really an option).
Is there any way around this?
One possibility is to wrap TxRx in a mockable class (i.e. one that has overridable methods and properties which you wish to mock out or implements an interface which defines the properties or methods that you're interested in) and then pass around the wrapper rather than the LinqToSQL class itself.
Perhaps something like the following:
public class TxRxWrapper : ITxRxWrapper
{
private TxRx m_txrx;
public object LastMod
{
get { return m_txrx.Common.LastMod; }
}
...
}
public interface ITxRxWrapper
{
public object LastMod { get; }
...
}
Not ideal (i.e. it can get somewhat cumbersome to pass wrappers around just for mockability!) but that's the only way you can get RhinoMocks to mock properties/methods for you.
The other option is to use TypeMock instead which I believe uses a different mechanism to mock stuff out. I don't think it's free, though.
You would need to replace your second expectation with
txRx.Expect(() => common.LastMod).SetPropertyAndIgnoreArgument();
But the Common property itself needs to be virtual for this to work.

NHibernate component mapping - Null Component

I have a mapped entity, Matter, that has a mapped component, Injury.
The only property on the Injury is DateOfInjury which is a nullable datetime.
When I retrieve the Matter, if the DateOfInjury is null, the component is null.
Thus something like this matter.Injury.DateOfInjury will throw.
Could someone explain if I am doing something obvious to cause this behaviour?
I would have expected that the Injury component gets initialized by nHibernate as an object and that the DateOfinjury property is null.
This would be more flexible i would think?
I think that's the default behavior for a component mapping. The NHibernate docs for component say that if all elements of the component are null, the component itself will just be null.
If you only have a single property in the component, it might make sense to just map it as a nullable DateTime property on the Matter class.
I also ran into the same problem of expecting NHibernate to initialize my component even if all its members are null in the DB. My motivation behind this implementation was to move as much logic concerning my component into the component, not having to deal with it being null or not.
Thanks to this post my search for an explanation why my unit tests were failing for all null values inside the component was short. I fixed this piece in the puzzle by extending the auto-property of my component class ArrivalDay and assigning a fresh instance myself when null is assigned:
private ArrivalDay _arrivalDay;
public ArrivalDay ArrivalDay
{
get { return _arrivalDay; }
set { _arrivalDay = value ?? new ArrivalDay(); }
}
This works like a charm and means very little overhead on the containing class.
I've resolved this by adding this property to my component class
public virtual bool _LoadAlways { get { return true; } set { } }
https://stackoverflow.com/a/11187173/206297 didn't work for me, but building on it:
public class Injury
{
// ...
private bool dummyFieldToLoadEmptyComponent { get; set; }
}
public class MatterMap : ClassMap<Matter>
{
// ...
Component(x => x.Injury, m =>
{
// ...
m.Map(Reveal.Member<Injury>("dummyFieldToLoadEmptyComponent")).Formula("1=1").ReadOnly();
});
}
The Reveal.Member bit is just to map a private field in Fluent NHibernate. We want the field private because we don't want that property exposed as part of our public interface to the component. See https://github.com/jagregory/fluent-nhibernate/wiki/Mapping-private-properties. If you don't mind having it public, you could use the less verbose mapping of:
m.Map(x => x.DummyFieldToLoadEmptyComponent).Formula("1=1").ReadOnly();
The Formula part is because we don't actually want a column in our DB for this. NHibernate will execute that formula when loading the component, and it'll always evaluate to true. I chose 1=1 as I would imagine that's reasonably cross-DB.
Undoubtedly a hack, but seems to work so far for loading empty components and hasn't caused any errors when persisting. Use with discretion though.
This is a technically workable solution. I have tested it with persistance and havent produced transient related issues.
protected internal virtual Injury NullableInjury {get;set;}
public virtual Injury Injury
{
get{return NullableInjury ?? (NullableInjury = new Injury());
}
In Nhibernate map your component to the NullableInjury.
This solution allows you to persist without the transient issue reported in #Oliver solution.