Override modelsbuilder or ensure that destination for package has modelsbuilder turned on
Hi all,
I've been looking around and can't seem to find a straightforward answer for my scenario.
I am in the process of creating a package and have some partial views and generated models that I would like to include. These generated models are also referenced in a couple of controllers, so they definitely need to be included. My issue is that I want to include these generated view models without them conflicting with any generated models in projects that have SourceCodeManual models mode set up.
I have seen that you can override the default models builder by replacing it (https://atomictoolkit.com/blog/how-to-use-models-builder-models-in-your-umbraco-package/), but the issue is that if every package replaces the models builder then packages will conflict and any other packages using this approach installed after will replace my implementation and break it.
An alternative would be ensuring that any destination Umbraco projects that the package is installed into have modelsbuilder enabled so that the required models are generated by the project, but I can't figure out how to do this.
The typical rule of thumb for public packages (Where you don't control their usage) is not to rely on Umbraco Models Builder for your views/controllers etc. Instead it best to use the "stringly typed" approach and convert IPublishedContent to your own custom view model.
This allows for you to maintain control, also allows for better "checks" for properties incase things are removed by consumers of your package (I've seen this happen).
By shipping with Umbraco Models Builder generated models you run the risk of conflicts so I would strongly advise avoiding it if you can.
Hmm, ok. So if I want a pseudo strongly typed class I could make a class with a constructor that takes an IPublishedContent parameter and then try get the values? Like:
public class MyModel
{
private readonly IPublishedElement _content;
public ContactForm(IPublishedElement content)
{
_content = content;
}
public Guid Key => _content.Key;
public string? Title => _content.Value<string>("title");
}
and then instead of casting the content, create a new instance of my model:
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
@{
var content = (ContentModels.GeneratedModel)Model.Content;
}
becomes
@using MyModels = MyProject.Models;
@{
var content = new MyModels.MyModel(Model.Content);
}
Or do you believe that there is a better way? I don't want to use content.Value("myVal") in every view and I think even a pseudo strong class is better because it is used in the controller.
Override modelsbuilder or ensure that destination for package has modelsbuilder turned on
Hi all,
I've been looking around and can't seem to find a straightforward answer for my scenario.
I am in the process of creating a package and have some partial views and generated models that I would like to include. These generated models are also referenced in a couple of controllers, so they definitely need to be included. My issue is that I want to include these generated view models without them conflicting with any generated models in projects that have SourceCodeManual models mode set up.
I have seen that you can override the default models builder by replacing it (https://atomictoolkit.com/blog/how-to-use-models-builder-models-in-your-umbraco-package/), but the issue is that if every package replaces the models builder then packages will conflict and any other packages using this approach installed after will replace my implementation and break it.
I also saw a post that said that you could override models builder files to avoid conflicts (https://our.umbraco.com/forum/using-umbraco-and-getting-started/76992-models-builder-gripes#comment-246101) but that was a post from 9 years ago and seems to no longer work.
An alternative would be ensuring that any destination Umbraco projects that the package is installed into have modelsbuilder enabled so that the required models are generated by the project, but I can't figure out how to do this.
Any help is much appreciated.
Thanks.
Hi Adam,
The typical rule of thumb for public packages (Where you don't control their usage) is not to rely on Umbraco Models Builder for your views/controllers etc. Instead it best to use the "stringly typed" approach and convert IPublishedContent to your own custom view model.
This allows for you to maintain control, also allows for better "checks" for properties incase things are removed by consumers of your package (I've seen this happen).
By shipping with Umbraco Models Builder generated models you run the risk of conflicts so I would strongly advise avoiding it if you can.
Nik
Hi Nik.
Hmm, ok. So if I want a pseudo strongly typed class I could make a class with a constructor that takes an IPublishedContent parameter and then try get the values? Like:
and then instead of casting the content, create a new instance of my model:
becomes
Or do you believe that there is a better way? I don't want to use content.Value("myVal") in every view and I think even a pseudo strong class is better because it is used in the controller.
Thanks, Adam.
is working on a reply...