How to upgrade abp 5.14 to abp 6.0? - aspnetboilerplate

Abp new version 6.0 come out. My project version is 5.14.0, core 3.1, use Startup Templates, how to safe upgrade to abp v6.0?
Thank you.

Completed this upgrade myself - very straightforward.
step 1:
Change every project to use:
<TargetFramework>net5.0</TargetFramework>
step 2:
There's a small breaking change in this class's constructor. Code shown below I simply copied over the code from the new the new version to get it working:
public class UserStore : AbpUserStore<Role, User>
{
public UserStore(
IUnitOfWorkManager unitOfWorkManager,
IRepository<User, long> userRepository,
IRepository<Role> roleRepository,
IRepository<UserRole, long> userRoleRepository,
IRepository<UserLogin, long> userLoginRepository,
IRepository<UserClaim, long> userClaimRepository,
IRepository<UserPermissionSetting, long> userPermissionSettingRepository,
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
IRepository<OrganizationUnitRole, long> organizationUnitRoleRepository)
: base(unitOfWorkManager,
userRepository,
roleRepository,
userRoleRepository,
userLoginRepository,
userClaimRepository,
userPermissionSettingRepository,
userOrganizationUnitRepository,
organizationUnitRoleRepository
)
{
}
}

The target framework and abp packages should be updated in each project:
<TargetFramework>net5.0</TargetFramework>
If you currently have the following you must change it to 6.0
<PackageReference Include="Abp.Castle.Log4Net" Version="5.13.0" />
Change by:
<PackageReference Include="Abp.Castle.Log4Net" Version="6.0" />

Related

Quarkus extension using a repository based on PanacheMongoRepository

I'm currently working on a Quarkus extension which is basically a filter that is using a PanacheMongoRepository. Here is a code snippet (this is in the runtime part of the extension) :
#Provider
#Priority(Priorities.AUTHORIZATION)
#AuthorizationSecured
public class AuthorizationFilter implements ContainerRequestFilter {
// Some injection here
#Inject
UserRepository userRepository;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// Some business logic here...
UserEntity userEntity = userRepository.findByName(name);
// Some business logic here...
}
}
The repository :
#ApplicationScoped
public class UserRepository implements PanacheMongoRepository<UserEntity> {
public UserEntity findByName(String name) {
return find("some query...", name).firstResult();
}
}
When the repository is called, I get the following exception:
org.jboss.resteasy.spi.UnhandledException: java.lang.IllegalStateException: This method is normally automatically overridden in subclasses...
java.lang.IllegalStateException: This method is normally automatically overridden in subclasses\n\tat io.quarkus.mongodb.panache.common.runtime.MongoOperations.implementationInjectionMissing(MongoOperations.java:765)\n\tat io.quarkus.mongodb.panache.PanacheMongoRepositoryBase.find(PanacheMongoRepositoryBase.java:119)
The processor
class AuthorizeProcessor {
private static final String FEATURE = "authorize";
#BuildStep
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}
#BuildStep(onlyIf = IsAuthorizeEnabled.class)
void registerAuthorizeFilter(
BuildProducer<AdditionalBeanBuildItem> additionalBeanProducer,
BuildProducer<ResteasyJaxrsProviderBuildItem> resteasyJaxrsProviderProducer
) {
additionalBeanProducer.produce(new AdditionalBeanBuildItem(UserRepository.class));
additionalBeanProducer.produce(new AdditionalBeanBuildItem(AuthorizationFilter.class));
resteasyJaxrsProviderProducer.produce(new ResteasyJaxrsProviderBuildItem(AuthorizationFilter.class.getName()));
}
}
Any idea ?
Thanks for your help :)
MongoDB with Panache (and the same for Hibernate with Panache) uses bytecode enhancement at build time. When this enhancement didn't occurs it leads to the exception you mentionned at runtime: java.lang.IllegalStateException: This method is normally automatically overridden in subclasses
It can occurs only when the repository or entity is not in the Jandex index. Jandex is used to index all the code of your application to avoid using reflection and classpath scanning to discover classes. If your entity / repository is not in the index this means it's not part of your application as we automatically index the classes of your application, so it must be inside an external JAR.
Usually, this is solved by adding the Jandex plugin to index the code of the external JAR (in fact there is multiple way to do this, see How to Generate a Jandex Index).
An extension suffer from the same issue as extensions are not indexed by default. But from an extension you can index the needed classes via a build step wich is more easy and avoid polluting the index with classes that are not needed.
This can be done by generating a new AdditionalIndexedClassesBuildItem(UserRepository.class.getName()) inside a build step.

How to use Session in Models in MVC .NET Core 2.2

I want to use Session in a MVC .NET Core 2.2 project but not only in the Controller but also in the Model.
There are examples to show the usage in Controllers but I did not find any information on how to access the Session in Model classes. Also I need to say that Models are not in the Web project but in a seperate Class Library project.
Is there a proper answer or solution for this problem?
It's generally inadvisable to use the session in a class library.You'd better pass the particular values to your library call or just pass the whole IHttpContextAccessor to get HttpContext in model class.
So instead of accessing the settings in the library method, you do:
1.Class Library.
1) Install below packages for your Class Library:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
</ItemGroup>
2) Model:
using Microsoft.AspNetCore.Http;
using System;
namespace ClassLibrary1
{
public class Product
{
private readonly IHttpContextAccessor _contextAccessor;
public Product(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
Name = _contextAccessor.HttpContext.Session.GetString("your session key");
}
public string Name { get; set; }
}
}
2.Web App.
1) Startup.cs
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
2) Controller:
public class HomeController : Controller
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
var product = new ClassLibrary1.Product(_httpContextAccessor );
}
}

Entity Framework Core 1.1.2's DbSet implementation

I am writing a new database provider for Entity Framework Core 1.1.2 (with target framework: .NET 4.5.2), and I have a very frustrating issue. My relevant installed NuGet packages are:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Relational
Microsoft.EntityFrameworkCore.SqlServer
I have a MyDbSet class which inherits from Microsoft.EntityFrameworkCore.DbSet:
public class MyDbSet<TEntity> : DbSet<TEntity> where TEntity : class {
}
I have a context class which is as simple as:
public class MyContext : DbContext {
public MyDbSet<MyOtherModel> Others { get; set; }
// Constructor
public MyModel() {
others = new MyDbSet<MyOtherModel>();
}
}
I instantiate a MyContext object,
MyContext myContext = new MyContext();
and I want to do the following:
myContext.Others.Add(new MyOtherModel());
Here I receive an exception saying that the Add method is unimplemented.
Seeing the EF Core documentations, DbSet really is an abstract class with abstract, unimplemented methods. Is it right? Should I really write my own DbSet implementation? Or is there a default implementation of it somewhere? If so, which assembly / NuGet package do I need to access this?

Dependency Injection with dynamically instanciated class with Spring Boot

I'm trying to develop a spring-boot application which offer the possibility for the user to create and call some simple workflows.
The steps of the workflows are already written (they all extends the same class), and, when the user create a workflow, he/she just pick which steps he wants to include in his it. The steps and the workflows are saved in a database.
My problem comes when the user call the workflow: I want to instanciate dynamically each step using the class loader but with the dependencies injected by spring!
Here is an example of a plug-in:
public class HelloWorldStepPlugin extends StepPlugin {
private static final Logger LOG = LogManager.getLogger();
#Autowired
private HelloWorldRepository repository;
public HelloWorldStepPlugin() {
super(HelloWorldStepPlugin.class.getSimpleName());
}
#Override
public void process() {
LOG.info("Hello world!");
this.repository.findAll(); // <= throw a NullPointerException because this.repository is null
}
}
Here is how I execute a Workflow (in another class):
ClassLoader cl = getClass().getClassLoader();
for (Step s : workflow.getSteps()) {
StepPlugin sp = (StepPlugin) cl.loadClass(STEP_PLUGIN_PACKAGE + s.getPlugin()).newInstance();
sp.process();
}
How can I do to have my HelloWorldRepository injected by Spring?
Is there a much better approach to do what I intend to?
I suggest you declare your steps as prototype beans. Instead of saving class names in the database, save bean names. Then get the steps and the plugins from the spring context (i.e. using getBean()).

Robospice Impossible to start SpiceManager as no service of class

I am trying to use following libraries to develop my app.
Robospice
Gson
and Spring for android
To do so, In my gradle file I have following dependencies added
compile 'com.octo.android.robospice:robospice-spring-android:1.4.13'
compile 'com.google.code.gson:gson:2.2.4'
And in manifest file, I have following lines inserted inside application tag.
<service
android:name="com.octo.android.robospice.GsonSpringAndroidSpiceService"
android:exported="false" />
Now, I created a base class that is used as Base Activity. And, I have did this in the following way:
public class BaseSpiceActivity extends Activity {
private SpiceManager spiceManager = new SpiceManager(GsonSpringAndroidSpiceService.class);
#Override
protected void onStart() {
spiceManager.start(this);
super.onStart();
}
#Override
protected void onStop() {
spiceManager.shouldStop();
super.onStop();
}
protected SpiceManager getSpiceManager() {
return spiceManager;
}
}
And then I used that base class to extend my own class where I had to use spice service request.
SimpleTextRequest text = new SimpleTextRequest(placeUrl);
getSpiceManager().execute(text, "place", DurationInMillis.ONE_MINUTE, new RequestListener<String>() {
//Other functions and codes
}
)
But when the above code gets executed, I am getting following error
E/AndroidRuntime﹕ FATAL EXCEPTION: SpiceManagerThread 0
java.lang.RuntimeException: Impossible to start SpiceManager as no service of class : com.octo.android.robospice.SpiceService is registered in AndroidManifest.xml file !
at com.octo.android.robospice.SpiceManager.checkServiceIsProperlyDeclaredInAndroidManifest(SpiceManager.java:1287)
at com.octo.android.robospice.SpiceManager.tryToStartService(SpiceManager.java:1168)
at com.octo.android.robospice.SpiceManager.run(SpiceManager.java:247)
at java.lang.Thread.run(Thread.java:856)
I have been trying to solve the issue from many hours. But unfortunately couldn't. Please help me out.
I am 100% sure you got messed somewhere. Search for new SpiceManager(SpiceService.class); in your code, and you will find out that you do use this service instead of the desired GsonSpringAndroidSpiceService.
You need to declare your service in your manifest.xml
Like this
<service android:name=".SampleRetrofitService"
android:exported="false"/>
Try to find out where using SpiceManager.
In my case, I named a activity SpiceActivity, and others extend it.
But robospice library also offer a activity named SpiceActivity. And it uses new SpiceManager(SpiceService.class)
So activity extends the wrong SpiceActivity which use SpiceService, then cause the error.

Resources